Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add extra annotations for cms and secrets #164

Merged
merged 1 commit into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,25 @@ spec:
From now on, when a mounted ConfigMap or Secret is updated, Wave will update
this `config-hash` annotation and cause a Rolling Update to occur.

### Advanced Features

If your Pod is reading some ConfigMap or Secret using the API and you want it
to be restarted on change you can tell Wave in an annotation:

```
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
wave.pusher.com/update-on-config-change: "true"
wave.pusher.com/extra-configmaps: "some-namespace/my-configmap,configmap-in-same-namespace"
wave.pusher.com/extra-secrets: "some-namespace/my-secret,some-other-namespace/foo"
...
```

Wave will watch those ConfigMap or Secret and behave just like if they were
mounted.

## Project Concepts

This section outlines some of the underlying concepts that enable this
Expand Down
24 changes: 24 additions & 0 deletions pkg/core/children.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ func getChildNamesByType(obj podController) (configMetadataMap, configMetadataMa
}
}
}

// Parse deployment annotations for cms/secrets used inside the pod
if annotations := obj.GetAnnotations(); annotations != nil {
if configMapString, ok := annotations[ExtraConfigMapsAnnotation]; ok {
for _, cm := range strings.Split(configMapString, ",") {
parts := strings.Split(cm, "/")
if len(parts) == 1 {
configMaps[GetNamespacedName(parts[0], obj.GetNamespace())] = configMetadata{required: false, allKeys: true}
} else if len(parts) == 2 {
configMaps[GetNamespacedName(parts[1], parts[0])] = configMetadata{required: false, allKeys: true}
}
}
}
if secretString, ok := annotations[ExtraSecretsAnnotation]; ok {
for _, secret := range strings.Split(secretString, ",") {
parts := strings.Split(secret, "/")
if len(parts) == 1 {
secrets[GetNamespacedName(parts[0], obj.GetNamespace())] = configMetadata{required: false, allKeys: true}
} else if len(parts) == 2 {
secrets[GetNamespacedName(parts[1], parts[0])] = configMetadata{required: false, allKeys: true}
}
}
}
}
}

// Range through all Containers and their respective EnvFrom,
Expand Down
22 changes: 20 additions & 2 deletions pkg/core/children_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,24 @@ var _ = Describe("Wave children Suite", func() {
configMaps, secrets = getChildNamesByType(podControllerDeployment)
})

It("returns ConfigMaps referenced in extra-configmaps annotations", func() {
Expect(configMaps).To(HaveKeyWithValue(GetNamespacedName("test-cm1", "ns1"),
configMetadata{required: false, allKeys: true}))
Expect(configMaps).To(HaveKeyWithValue(GetNamespacedName("test-cm2", "ns2"),
configMetadata{required: false, allKeys: true}))
Expect(configMaps).To(HaveKeyWithValue(GetNamespacedName("local-cm1", podControllerDeployment.GetNamespace()),
configMetadata{required: false, allKeys: true}))
})

It("returns Secrets referenced in extra-secrets annotations", func() {
Expect(secrets).To(HaveKeyWithValue(GetNamespacedName("test-secret1", "ns1"),
configMetadata{required: false, allKeys: true}))
Expect(secrets).To(HaveKeyWithValue(GetNamespacedName("test-secret2", "ns2"),
configMetadata{required: false, allKeys: true}))
Expect(secrets).To(HaveKeyWithValue(GetNamespacedName("local-secret1", podControllerDeployment.GetNamespace()),
configMetadata{required: false, allKeys: true}))
})

It("returns ConfigMaps referenced in Volumes", func() {
Expect(configMaps).To(HaveKeyWithValue(GetNamespacedName(cm1.GetName(), podControllerDeployment.GetNamespace()),
configMetadata{required: true, allKeys: true}))
Expand Down Expand Up @@ -364,8 +382,8 @@ var _ = Describe("Wave children Suite", func() {
})

It("does not return extra children", func() {
Expect(configMaps).To(HaveLen(9))
Expect(secrets).To(HaveLen(9))
Expect(configMaps).To(HaveLen(12))
Expect(secrets).To(HaveLen(12))
})
})

Expand Down
8 changes: 8 additions & 0 deletions pkg/core/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ const (
// SchedulingDisabledSchedulerName is the dummy scheduler to disable scheduling of pods
SchedulingDisabledSchedulerName = "wave.pusher.com/invalid"

// ExtraConfigMapsAnnotation is the key of the annotation that contains additional
// ConfigMaps which Wave should watch
ExtraConfigMapsAnnotation = "wave.pusher.com/extra-configmaps"

// ExtraSecretsAnnotation is the key of the annotation that contains additional
// Secrets which Wave should watch
ExtraSecretsAnnotation = "wave.pusher.com/extra-secrets"

// RequiredAnnotation is the key of the annotation on the Deployment that Wave
// checks for before processing the deployment
RequiredAnnotation = "wave.pusher.com/update-on-config-change"
Expand Down
12 changes: 9 additions & 3 deletions test/utils/test_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ var labels = map[string]string{
"app": "example",
}

var annotations = map[string]string{
"wave.pusher.com/extra-configmaps": "ns1/test-cm1,ns2/test-cm2,local-cm1",
"wave.pusher.com/extra-secrets": "ns1/test-secret1,ns2/test-secret2,local-secret1",
}

var trueValue = true

// ExampleDeployment is an example Deployment object for use within test suites
var ExampleDeployment = &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "example",
Namespace: "default",
Labels: labels,
Name: "example",
Namespace: "default",
Labels: labels,
Annotations: annotations,
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
Expand Down
Loading