Skip to content

Commit 4d8b153

Browse files
authored
Merge pull request #433 from weaveworks/projected-configs
Track projected configmaps and secrets
2 parents ad68ca3 + c181eb4 commit 4d8b153

File tree

4 files changed

+277
-77
lines changed

4 files changed

+277
-77
lines changed

pkg/canary/config_tracker.go

+45
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,32 @@ func (ct *ConfigTracker) GetTargetConfigs(cd *flaggerv1.Canary) (map[string]Conf
124124
res[secret.GetName()] = *secret
125125
}
126126
}
127+
128+
if projected := volume.Projected; projected != nil {
129+
for _, source := range projected.Sources {
130+
if cmv := source.ConfigMap; cmv != nil {
131+
config, err := ct.getRefFromConfigMap(cmv.Name, cd.Namespace)
132+
if err != nil {
133+
ct.Logger.Errorf("configMap %s.%s query error %v", cmv.Name, cd.Namespace, err)
134+
continue
135+
}
136+
if config != nil {
137+
res[config.GetName()] = *config
138+
}
139+
}
140+
141+
if sv := source.Secret; sv != nil {
142+
secret, err := ct.getRefFromSecret(sv.Name, cd.Namespace)
143+
if err != nil {
144+
ct.Logger.Errorf("secret %s.%s query error %v", sv.Name, cd.Namespace, err)
145+
continue
146+
}
147+
if secret != nil {
148+
res[secret.GetName()] = *secret
149+
}
150+
}
151+
}
152+
}
127153
}
128154
// scan containers
129155
for _, container := range targetDep.Spec.Template.Spec.Containers {
@@ -335,7 +361,26 @@ func (ct *ConfigTracker) ApplyPrimaryConfigs(spec corev1.PodSpec, refs map[strin
335361
spec.Volumes[i].Secret.SecretName += "-primary"
336362
}
337363
}
364+
365+
if projected := volume.Projected; projected != nil {
366+
for s, source := range projected.Sources {
367+
if cmv := source.ConfigMap; cmv != nil {
368+
name := fmt.Sprintf("%s/%s", ConfigRefMap, cmv.Name)
369+
if _, exists := refs[name]; exists {
370+
spec.Volumes[i].Projected.Sources[s].ConfigMap.Name += "-primary"
371+
}
372+
}
373+
374+
if sv := source.Secret; sv != nil {
375+
name := fmt.Sprintf("%s/%s", ConfigRefSecret, sv.Name)
376+
if _, exists := refs[name]; exists {
377+
spec.Volumes[i].Projected.Sources[s].Secret.Name += "-primary"
378+
}
379+
}
380+
}
381+
}
338382
}
383+
339384
// update containers
340385
for _, container := range spec.Containers {
341386
// update env

pkg/canary/config_tracker_test.go

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package canary
2+
3+
import (
4+
"testing"
5+
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
)
8+
9+
func TestConfigTracker_ConfigMaps(t *testing.T) {
10+
mocks := newFixture()
11+
configMap := newTestConfigMap()
12+
configMapProjected := newTestConfigProjected()
13+
14+
err := mocks.deployer.Initialize(mocks.canary, true)
15+
if err != nil {
16+
t.Fatal(err.Error())
17+
}
18+
19+
depPrimary, err := mocks.kubeClient.AppsV1().Deployments("default").Get("podinfo-primary", metav1.GetOptions{})
20+
if err != nil {
21+
t.Fatal(err.Error())
22+
}
23+
24+
configPrimaryVolName := depPrimary.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.LocalObjectReference.Name
25+
if configPrimaryVolName != "podinfo-config-vol-primary" {
26+
t.Errorf("Got config name %v wanted %v", configPrimaryVolName, "podinfo-config-vol-primary")
27+
}
28+
29+
configPrimary, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-env-primary", metav1.GetOptions{})
30+
if err != nil {
31+
t.Fatal(err.Error())
32+
}
33+
34+
if configPrimary.Data["color"] != configMap.Data["color"] {
35+
t.Errorf("Got ConfigMap color %s wanted %s", configPrimary.Data["color"], configMap.Data["color"])
36+
}
37+
38+
configPrimaryEnv, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-all-env-primary", metav1.GetOptions{})
39+
if err != nil {
40+
t.Fatal(err.Error())
41+
}
42+
43+
if configPrimaryEnv.Data["color"] != configMap.Data["color"] {
44+
t.Errorf("Got ConfigMap %s wanted %s", configPrimaryEnv.Data["a"], configMap.Data["color"])
45+
}
46+
47+
configPrimaryVol, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-vol-primary", metav1.GetOptions{})
48+
if err != nil {
49+
t.Fatal(err.Error())
50+
}
51+
52+
if configPrimaryVol.Data["color"] != configMap.Data["color"] {
53+
t.Errorf("Got ConfigMap color %s wanted %s", configPrimary.Data["color"], configMap.Data["color"])
54+
}
55+
56+
configProjectedName := depPrimary.Spec.Template.Spec.Volumes[2].VolumeSource.Projected.Sources[0].ConfigMap.Name
57+
if configProjectedName != "podinfo-config-projected-primary" {
58+
t.Errorf("Got config name %v wanted %v", configProjectedName, "podinfo-config-projected-primary")
59+
}
60+
61+
configPrimaryProjected, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-vol-primary", metav1.GetOptions{})
62+
if err != nil {
63+
t.Fatal(err.Error())
64+
}
65+
66+
if configPrimaryProjected.Data["color"] != configMapProjected.Data["color"] {
67+
t.Errorf("Got ConfigMap color %s wanted %s", configPrimaryProjected.Data["color"], configMapProjected.Data["color"])
68+
}
69+
}
70+
71+
func TestConfigTracker_Secrets(t *testing.T) {
72+
mocks := newFixture()
73+
secret := newTestSecret()
74+
secretProjected := newTestSecretProjected()
75+
76+
err := mocks.deployer.Initialize(mocks.canary, true)
77+
if err != nil {
78+
t.Fatal(err.Error())
79+
}
80+
81+
depPrimary, err := mocks.kubeClient.AppsV1().Deployments("default").Get("podinfo-primary", metav1.GetOptions{})
82+
if err != nil {
83+
t.Fatal(err.Error())
84+
}
85+
86+
secretPrimaryVolName := depPrimary.Spec.Template.Spec.Volumes[1].VolumeSource.Secret.SecretName
87+
if secretPrimaryVolName != "podinfo-secret-vol-primary" {
88+
t.Errorf("Got config name %v wanted %v", secretPrimaryVolName, "podinfo-secret-vol-primary")
89+
}
90+
91+
secretPrimary, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-env-primary", metav1.GetOptions{})
92+
if err != nil {
93+
t.Fatal(err.Error())
94+
}
95+
96+
if string(secretPrimary.Data["apiKey"]) != string(secret.Data["apiKey"]) {
97+
t.Errorf("Got primary secret %s wanted %s", secretPrimary.Data["apiKey"], secret.Data["apiKey"])
98+
}
99+
100+
secretPrimaryEnv, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-all-env-primary", metav1.GetOptions{})
101+
if err != nil {
102+
t.Fatal(err.Error())
103+
}
104+
105+
if string(secretPrimaryEnv.Data["apiKey"]) != string(secret.Data["apiKey"]) {
106+
t.Errorf("Got primary secret %s wanted %s", secretPrimary.Data["apiKey"], secret.Data["apiKey"])
107+
}
108+
109+
secretPrimaryVol, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-vol-primary", metav1.GetOptions{})
110+
if err != nil {
111+
t.Fatal(err.Error())
112+
}
113+
114+
if string(secretPrimaryVol.Data["apiKey"]) != string(secret.Data["apiKey"]) {
115+
t.Errorf("Got primary secret %s wanted %s", secretPrimary.Data["apiKey"], secret.Data["apiKey"])
116+
}
117+
118+
secretProjectedName := depPrimary.Spec.Template.Spec.Volumes[2].VolumeSource.Projected.Sources[1].Secret.Name
119+
if secretProjectedName != "podinfo-secret-projected-primary" {
120+
t.Errorf("Got config name %v wanted %v", secretProjectedName, "podinfo-secret-projected-primary")
121+
}
122+
123+
secretPrimaryProjected, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-projected-primary", metav1.GetOptions{})
124+
if err != nil {
125+
t.Fatal(err.Error())
126+
}
127+
128+
if string(secretPrimaryProjected.Data["apiKey"]) != string(secretProjected.Data["apiKey"]) {
129+
t.Errorf("Got primary secret %s wanted %s", secretPrimaryProjected.Data["apiKey"], secretProjected.Data["apiKey"])
130+
}
131+
}

pkg/canary/deployment_controller_test.go

+1-62
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,7 @@ func TestCanaryDeployer_Sync(t *testing.T) {
2121
t.Fatal(err.Error())
2222
}
2323

24-
configName := depPrimary.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.LocalObjectReference.Name
25-
if configName != "podinfo-config-vol-primary" {
26-
t.Errorf("Got config name %v wanted %v", configName, "podinfo-config-vol-primary")
27-
}
28-
2924
dep := newTestDeployment()
30-
configMap := NewTestConfigMap()
31-
secret := NewTestSecret()
3225

3326
primaryImage := depPrimary.Spec.Template.Spec.Containers[0].Image
3427
sourceImage := dep.Spec.Template.Spec.Containers[0].Image
@@ -44,60 +37,6 @@ func TestCanaryDeployer_Sync(t *testing.T) {
4437
if hpaPrimary.Spec.ScaleTargetRef.Name != depPrimary.Name {
4538
t.Errorf("Got HPA target %s wanted %s", hpaPrimary.Spec.ScaleTargetRef.Name, depPrimary.Name)
4639
}
47-
48-
configPrimary, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-env-primary", metav1.GetOptions{})
49-
if err != nil {
50-
t.Fatal(err.Error())
51-
}
52-
53-
if configPrimary.Data["color"] != configMap.Data["color"] {
54-
t.Errorf("Got ConfigMap color %s wanted %s", configPrimary.Data["color"], configMap.Data["color"])
55-
}
56-
57-
configPrimaryEnv, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-all-env-primary", metav1.GetOptions{})
58-
if err != nil {
59-
t.Fatal(err.Error())
60-
}
61-
62-
if configPrimaryEnv.Data["color"] != configMap.Data["color"] {
63-
t.Errorf("Got ConfigMap %s wanted %s", configPrimaryEnv.Data["a"], configMap.Data["color"])
64-
}
65-
66-
configPrimaryVol, err := mocks.kubeClient.CoreV1().ConfigMaps("default").Get("podinfo-config-vol-primary", metav1.GetOptions{})
67-
if err != nil {
68-
t.Fatal(err.Error())
69-
}
70-
71-
if configPrimaryVol.Data["color"] != configMap.Data["color"] {
72-
t.Errorf("Got ConfigMap color %s wanted %s", configPrimary.Data["color"], configMap.Data["color"])
73-
}
74-
75-
secretPrimary, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-env-primary", metav1.GetOptions{})
76-
if err != nil {
77-
t.Fatal(err.Error())
78-
}
79-
80-
if string(secretPrimary.Data["apiKey"]) != string(secret.Data["apiKey"]) {
81-
t.Errorf("Got primary secret %s wanted %s", secretPrimary.Data["apiKey"], secret.Data["apiKey"])
82-
}
83-
84-
secretPrimaryEnv, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-all-env-primary", metav1.GetOptions{})
85-
if err != nil {
86-
t.Fatal(err.Error())
87-
}
88-
89-
if string(secretPrimaryEnv.Data["apiKey"]) != string(secret.Data["apiKey"]) {
90-
t.Errorf("Got primary secret %s wanted %s", secretPrimary.Data["apiKey"], secret.Data["apiKey"])
91-
}
92-
93-
secretPrimaryVol, err := mocks.kubeClient.CoreV1().Secrets("default").Get("podinfo-secret-vol-primary", metav1.GetOptions{})
94-
if err != nil {
95-
t.Fatal(err.Error())
96-
}
97-
98-
if string(secretPrimaryVol.Data["apiKey"]) != string(secret.Data["apiKey"]) {
99-
t.Errorf("Got primary secret %s wanted %s", secretPrimary.Data["apiKey"], secret.Data["apiKey"])
100-
}
10140
}
10241

10342
func TestCanaryDeployer_IsNewSpec(t *testing.T) {
@@ -284,7 +223,7 @@ func TestCanaryDeployer_SyncStatus(t *testing.T) {
284223
t.Fatalf("Status tracking configs are empty")
285224
}
286225
configs := *res.Status.TrackedConfigs
287-
secret := NewTestSecret()
226+
secret := newTestSecret()
288227
if _, exists := configs["secret/"+secret.GetName()]; !exists {
289228
t.Errorf("Secret %s not found in status", secret.GetName())
290229
}

0 commit comments

Comments
 (0)