Skip to content

Commit

Permalink
Merge pull request authzed#107 from mgagliardo91/feat-custom-annotations
Browse files Browse the repository at this point in the history
feat: allow custom annotations
  • Loading branch information
ecordell authored Nov 14, 2022
2 parents 1b313d9 + 845024e commit cac0628
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 22 deletions.
20 changes: 17 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ var (
datastoreEngineKey = newStringKey("datastoreEngine")
replicasKey = newIntOrStringKey("replicas", 2)
replicasKeyForMemory = newIntOrStringKey("replicas", 1)
extraPodLabelsKey = labelSetKey("extraPodLabels")
extraPodLabelsKey = metadataSetKey("extraPodLabels")
extraPodAnnotationsKey = metadataSetKey("extraPodAnnotations")
grpcTLSKeyPathKey = newKey("grpcTLSKeyPath", DefaultTLSKeyFile)
grpcTLSCertPathKey = newKey("grpcTLSCertPath", DefaultTLSCrtFile)
dispatchClusterTLSKeyPathKey = newKey("dispatchClusterTLSKeyPath", DefaultTLSKeyFile)
Expand Down Expand Up @@ -129,6 +130,7 @@ type SpiceConfig struct {
TelemetryTLSCASecretName string
SecretName string
ExtraPodLabels map[string]string
ExtraPodAnnotations map[string]string
Passthrough map[string]string
}

Expand All @@ -152,6 +154,7 @@ func NewConfig(nn types.NamespacedName, uid types.UID, currentState *SpiceDBMigr
EnvPrefix: envPrefixKey.pop(config),
SpiceDBCmd: spiceDBCmdKey.pop(config),
ExtraPodLabels: make(map[string]string, 0),
ExtraPodAnnotations: make(map[string]string, 0),
LogLevel: logLevelKey.pop(config),
}
migrationConfig := MigrationConfig{
Expand Down Expand Up @@ -233,15 +236,25 @@ func NewConfig(nn types.NamespacedName, uid types.UID, currentState *SpiceDBMigr
}

var labelWarnings []error
spiceConfig.ExtraPodLabels, labelWarnings, err = extraPodLabelsKey.pop(config)
spiceConfig.ExtraPodLabels, labelWarnings, err = extraPodLabelsKey.pop(config, "label")
if err != nil {
errs = append(errs, err)
}

if len(warnings) > 0 {
if len(labelWarnings) > 0 {
warnings = append(warnings, labelWarnings...)
}

var annotationWarnings []error
spiceConfig.ExtraPodAnnotations, annotationWarnings, err = extraPodAnnotationsKey.pop(config, "annotation")
if err != nil {
errs = append(errs, err)
}

if len(annotationWarnings) > 0 {
warnings = append(warnings, annotationWarnings...)
}

// generate secret refs for tls if specified
if len(spiceConfig.TLSSecretName) > 0 {
passthroughKeys := []*key[string]{
Expand Down Expand Up @@ -648,6 +661,7 @@ func (c *Config) Deployment(migrationHash, secretHash string) *applyappsv1.Deplo
WithLabels(map[string]string{"app.kubernetes.io/instance": name}).
WithLabels(metadata.LabelsForComponent(c.Name, metadata.ComponentSpiceDBLabelValue)).
WithLabels(c.ExtraPodLabels).
WithAnnotations(c.ExtraPodAnnotations).
WithSpec(applycorev1.PodSpec().WithServiceAccountName(c.Name).WithContainers(
applycorev1.Container().WithName(name).WithImage(c.TargetSpiceDBImage).
WithCommand(c.SpiceConfig.SpiceDBCmd, "serve").
Expand Down
107 changes: 107 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,113 @@ func TestNewConfig(t *testing.T) {
},
},
},
{
name: "set extra annotations as string",
args: args{
nn: types.NamespacedName{Namespace: "test", Name: "test"},
uid: types.UID("1"),
globalConfig: OperatorConfig{
ImageName: "image",
AllowedImages: []string{"image"},
},
rawConfig: json.RawMessage(`
{
"datastoreEngine": "cockroachdb",
"extraPodAnnotations": "app.kubernetes.io/name=test,app.kubernetes.io/managed-by=test-owner"
}
`),
secret: &corev1.Secret{Data: map[string][]byte{
"datastore_uri": []byte("uri"),
"preshared_key": []byte("psk"),
}},
},
wantWarnings: []error{fmt.Errorf("no TLS configured, consider setting \"tlsSecretName\"")},
want: &Config{
MigrationConfig: MigrationConfig{
MigrationLogLevel: "debug",
DatastoreEngine: "cockroachdb",
DatastoreURI: "uri",
TargetSpiceDBImage: "image",
EnvPrefix: "SPICEDB",
SpiceDBCmd: "spicedb",
TargetMigration: "head",
},
SpiceConfig: SpiceConfig{
LogLevel: "info",
SkipMigrations: false,
Name: "test",
Namespace: "test",
UID: "1",
Replicas: 2,
PresharedKey: "psk",
EnvPrefix: "SPICEDB",
SpiceDBCmd: "spicedb",
ExtraPodAnnotations: map[string]string{
"app.kubernetes.io/name": "test",
"app.kubernetes.io/managed-by": "test-owner",
},
Passthrough: map[string]string{
"datastoreEngine": "cockroachdb",
"dispatchClusterEnabled": "true",
},
},
},
},
{
name: "set extra annotations as map",
args: args{
nn: types.NamespacedName{Namespace: "test", Name: "test"},
uid: types.UID("1"),
globalConfig: OperatorConfig{
ImageName: "image",
AllowedImages: []string{"image"},
},
rawConfig: json.RawMessage(`
{
"datastoreEngine": "cockroachdb",
"extraPodAnnotations": {
"app.kubernetes.io/name": "test",
"app.kubernetes.io/managed-by": "test-owner"
}
}
`),
secret: &corev1.Secret{Data: map[string][]byte{
"datastore_uri": []byte("uri"),
"preshared_key": []byte("psk"),
}},
},
wantWarnings: []error{fmt.Errorf("no TLS configured, consider setting \"tlsSecretName\"")},
want: &Config{
MigrationConfig: MigrationConfig{
MigrationLogLevel: "debug",
DatastoreEngine: "cockroachdb",
DatastoreURI: "uri",
TargetSpiceDBImage: "image",
EnvPrefix: "SPICEDB",
SpiceDBCmd: "spicedb",
TargetMigration: "head",
},
SpiceConfig: SpiceConfig{
LogLevel: "info",
SkipMigrations: false,
Name: "test",
Namespace: "test",
UID: "1",
Replicas: 2,
PresharedKey: "psk",
EnvPrefix: "SPICEDB",
SpiceDBCmd: "spicedb",
ExtraPodAnnotations: map[string]string{
"app.kubernetes.io/name": "test",
"app.kubernetes.io/managed-by": "test-owner",
},
Passthrough: map[string]string{
"datastoreEngine": "cockroachdb",
"dispatchClusterEnabled": "true",
},
},
},
},
{
name: "skip migrations bool",
args: args{
Expand Down
20 changes: 10 additions & 10 deletions pkg/config/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,38 +102,38 @@ func (k *boolOrStringKey) pop(config RawConfig) (out bool, err error) {
return
}

type labelSetKey string
type metadataSetKey string

func (k labelSetKey) pop(config RawConfig) (podLabels map[string]string, warnings []error, err error) {
func (k metadataSetKey) pop(config RawConfig, metadataType string) (podMetadata map[string]string, warnings []error, err error) {
v, ok := config[string(k)]
delete(config, string(k))
if !ok {
return
}

podLabels = make(map[string]string)
podMetadata = make(map[string]string)

switch value := v.(type) {
case string:
if len(value) > 0 {
extraPodLabelPairs := strings.Split(value, ",")
for _, p := range extraPodLabelPairs {
extraPodMetadataPairs := strings.Split(value, ",")
for _, p := range extraPodMetadataPairs {
k, v, ok := strings.Cut(p, "=")
if !ok {
warnings = append(warnings, fmt.Errorf("couldn't parse extra pod label %q: labels should be of the form k=v,k2=v2", p))
warnings = append(warnings, fmt.Errorf("couldn't parse extra pod %s %q: values should be of the form k=v,k2=v2", metadataType, p))
continue
}
podLabels[k] = v
podMetadata[k] = v
}
}
case map[string]any:
for k, v := range value {
labelValue, ok := v.(string)
metadataValue, ok := v.(string)
if !ok {
warnings = append(warnings, fmt.Errorf("couldn't parse extra pod label %v", v))
warnings = append(warnings, fmt.Errorf("couldn't parse extra pod %s %v", metadataType, v))
continue
}
podLabels[k] = labelValue
podMetadata[k] = metadataValue
}
default:
err = fmt.Errorf("expected string or map for key %s", k)
Expand Down
6 changes: 3 additions & 3 deletions pkg/config/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func TestIntOrStringKey(t *testing.T) {
}
}

func TestLabelSetKey(t *testing.T) {
func TestMetadataSetKey(t *testing.T) {
input := map[string]any{"k": "v", "k2": "v2"}
invalidInput := map[string]any{"k": 1, "k2": "v2"}
empty := map[string]string{}
Expand All @@ -125,12 +125,12 @@ func TestLabelSetKey(t *testing.T) {
{"recovers and warns on invalid map value", invalidInput, empty, map[string]string{"k2": "v2"}, true, false},
} {
t.Run(val.description, func(t *testing.T) {
k := labelSetKey("test")
k := metadataSetKey("test")
config := emptyConfig
if val.value != nil {
config = RawConfig{"test": val.value}
}
result, warns, err := k.pop(config)
result, warns, err := k.pop(config, "metadata")
if val.value != nil {
require.Empty(t, config)
}
Expand Down
14 changes: 8 additions & 6 deletions pkg/controller/validate_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ func TestValidateConfigHandler(t *testing.T) {
expectNext: nextKey,
},
{
name: "valid config with warnings",
name: "valid config with label warnings",
currentStatus: &v1alpha1.SpiceDBCluster{Status: v1alpha1.ClusterStatus{Image: "image"}},
rawConfig: json.RawMessage(`{
"datastoreEngine": "cockroachdb",
"extraPodLabels": "wrong:format"
"extraPodLabels": "wrong:format",
"extraPodAnnotations": "annotation:bad"
}`),
existingSecret: &corev1.Secret{
Data: map[string][]byte{
Expand Down Expand Up @@ -159,12 +160,13 @@ func TestValidateConfigHandler(t *testing.T) {
currentStatus: &v1alpha1.SpiceDBCluster{Status: v1alpha1.ClusterStatus{Image: "image", Conditions: []metav1.Condition{{
Type: "ConfigurationWarning",
Status: metav1.ConditionTrue,
Message: "[couldn't parse extra pod label \"wrong:format\": labels should be of the form k=v,k2=v2, no TLS configured, consider setting \"tlsSecretName\"]",
Message: "[couldn't parse extra pod label \"wrong:format\": values should be of the form k=v,k2=v2, couldn't parse extra pod annotation \"annotation:bad\": values should be of the form k=v,k2=v2, no TLS configured, consider setting \"tlsSecretName\"]",
}}}},
rawConfig: json.RawMessage(`{
"datastoreEngine": "cockroachdb",
"tlsSecretName": "secret",
"extraPodLabels": "correct=format,good=value"
"datastoreEngine": "cockroachdb",
"tlsSecretName": "secret",
"extraPodLabels": "correct=format,good=value",
"extraPodAnnotations": "annotation=works"
}`),
existingSecret: &corev1.Secret{
Data: map[string][]byte{
Expand Down

0 comments on commit cac0628

Please sign in to comment.