Skip to content

Commit 5cb343d

Browse files
authored
Merge pull request #799 from Nerja/main
Check if mandatory secrets/configmaps exist
2 parents 67f34f1 + 565b99e commit 5cb343d

File tree

3 files changed

+66
-17
lines changed

3 files changed

+66
-17
lines changed

pkg/canary/config_tracker.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -146,31 +146,29 @@ func (ct *ConfigTracker) GetTargetConfigs(cd *flaggerv1.Canary) (map[string]Conf
146146
return nil, fmt.Errorf("TargetRef.Kind invalid: %s", cd.Spec.TargetRef.Kind)
147147
}
148148

149-
type void struct{}
150-
var member void
151-
secretNames := map[string]void{}
152-
configMapNames := map[string]void{}
149+
secretNames := make(map[string]bool)
150+
configMapNames := make(map[string]bool)
153151

154152
// scan volumes
155153
for _, volume := range vs {
156154
if cmv := volume.ConfigMap; cmv != nil {
157155
name := cmv.Name
158-
configMapNames[name] = member
156+
configMapNames[name] = fieldIsMandatory(cmv.Optional)
159157
}
160158
if sv := volume.Secret; sv != nil {
161159
name := sv.SecretName
162-
secretNames[name] = member
160+
secretNames[name] = fieldIsMandatory(sv.Optional)
163161
}
164162

165163
if projected := volume.Projected; projected != nil {
166164
for _, source := range projected.Sources {
167165
if cmv := source.ConfigMap; cmv != nil {
168166
name := cmv.Name
169-
configMapNames[name] = member
167+
configMapNames[name] = fieldIsMandatory(cmv.Optional)
170168
}
171169
if sv := source.Secret; sv != nil {
172170
name := sv.Name
173-
secretNames[name] = member
171+
secretNames[name] = fieldIsMandatory(sv.Optional)
174172
}
175173
}
176174
}
@@ -183,10 +181,10 @@ func (ct *ConfigTracker) GetTargetConfigs(cd *flaggerv1.Canary) (map[string]Conf
183181
switch {
184182
case env.ValueFrom.ConfigMapKeyRef != nil:
185183
name := env.ValueFrom.ConfigMapKeyRef.LocalObjectReference.Name
186-
configMapNames[name] = member
184+
configMapNames[name] = fieldIsMandatory(env.ValueFrom.ConfigMapKeyRef.Optional)
187185
case env.ValueFrom.SecretKeyRef != nil:
188186
name := env.ValueFrom.SecretKeyRef.LocalObjectReference.Name
189-
secretNames[name] = member
187+
secretNames[name] = fieldIsMandatory(env.ValueFrom.SecretKeyRef.Optional)
190188
}
191189
}
192190
}
@@ -195,30 +193,37 @@ func (ct *ConfigTracker) GetTargetConfigs(cd *flaggerv1.Canary) (map[string]Conf
195193
switch {
196194
case envFrom.ConfigMapRef != nil:
197195
name := envFrom.ConfigMapRef.LocalObjectReference.Name
198-
configMapNames[name] = member
196+
configMapNames[name] = fieldIsMandatory(envFrom.ConfigMapRef.Optional)
199197
case envFrom.SecretRef != nil:
200198
name := envFrom.SecretRef.LocalObjectReference.Name
201-
secretNames[name] = member
199+
secretNames[name] = fieldIsMandatory(envFrom.SecretRef.Optional)
202200
}
203201
}
204202
}
205203

206204
res := make(map[string]ConfigRef)
207205

208-
for configMapName := range configMapNames {
206+
for configMapName, required := range configMapNames {
209207
config, err := ct.getRefFromConfigMap(configMapName, cd.Namespace)
210208
if err != nil {
211-
ct.Logger.Errorf("getRefFromConfigMap failed: %v", err)
209+
if required {
210+
return nil, fmt.Errorf("configmap %s.%s get query error: %w", configMapName, cd.Namespace, err)
211+
}
212+
ct.Logger.Errorf("configmap %s.%s get query failed: %w", configMapName, cd.Namespace, err)
212213
continue
213214
}
214215
if config != nil {
215216
res[config.GetName()] = *config
216217
}
217218
}
218-
for secretName := range secretNames {
219+
220+
for secretName, required := range secretNames {
219221
secret, err := ct.getRefFromSecret(secretName, cd.Namespace)
220222
if err != nil {
221-
ct.Logger.Errorf("getRefFromSecret failed: %v", err)
223+
if required {
224+
return nil, fmt.Errorf("secret %s.%s get query error: %v", secretName, cd.Namespace, err)
225+
}
226+
ct.Logger.Errorf("secret %s.%s get query failed: %v", secretName, cd.Namespace, err)
222227
continue
223228
}
224229
if secret != nil {
@@ -229,6 +234,13 @@ func (ct *ConfigTracker) GetTargetConfigs(cd *flaggerv1.Canary) (map[string]Conf
229234
return res, nil
230235
}
231236

237+
func fieldIsMandatory(p *bool) bool {
238+
if p == nil {
239+
return false
240+
}
241+
return !*p
242+
}
243+
232244
// GetConfigRefs returns a map of configs and their checksum
233245
func (ct *ConfigTracker) GetConfigRefs(cd *flaggerv1.Canary) (*map[string]string, error) {
234246
res := make(map[string]string)

pkg/canary/config_tracker_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ package canary
1818

1919
import (
2020
"context"
21+
"errors"
2122
"testing"
2223

2324
"github.com/stretchr/testify/assert"
2425
"github.com/stretchr/testify/require"
2526

2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/apimachinery/pkg/runtime"
29+
k8sTesting "k8s.io/client-go/testing"
2730
)
2831

2932
func TestConfigIsDisabled(t *testing.T) {
@@ -303,3 +306,29 @@ func TestConfigTracker_Secrets(t *testing.T) {
303306
assert.True(t, originalVolPresent, "Volume for original secret with disabled tracking should be present")
304307
})
305308
}
309+
310+
func TestConfigTracker_HasConfigChanged_ShouldReturnErrorWhenAPIServerIsDown(t *testing.T) {
311+
t.Run("secret", func(t *testing.T) {
312+
dc := deploymentConfigs{name: "podinfo", label: "name", labelValue: "podinfo"}
313+
mocks, kubeClient := newCustomizableFixture(dc)
314+
315+
kubeClient.PrependReactor("get", "secrets", func(action k8sTesting.Action) (bool, runtime.Object, error) {
316+
return true, nil, errors.New("server error")
317+
})
318+
319+
_, err := mocks.controller.configTracker.HasConfigChanged(mocks.canary)
320+
assert.Error(t, err)
321+
})
322+
323+
t.Run("configmap", func(t *testing.T) {
324+
dc := deploymentConfigs{name: "podinfo", label: "name", labelValue: "podinfo"}
325+
mocks, kubeClient := newCustomizableFixture(dc)
326+
327+
kubeClient.PrependReactor("get", "configmaps", func(action k8sTesting.Action) (bool, runtime.Object, error) {
328+
return true, nil, errors.New("server error")
329+
})
330+
331+
_, err := mocks.controller.configTracker.HasConfigChanged(mocks.canary)
332+
assert.Error(t, err)
333+
})
334+
}

pkg/canary/deployment_fixture_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ func (d deploymentControllerFixture) initializeCanary(t *testing.T) {
7878
}
7979

8080
func newDeploymentFixture(dc deploymentConfigs) deploymentControllerFixture {
81+
fixture, _ := newCustomizableFixture(dc)
82+
return fixture
83+
}
84+
85+
func newCustomizableFixture(dc deploymentConfigs) (deploymentControllerFixture, *fake.Clientset) {
8186
// init canary
8287
cc := canaryConfigs{targetName: dc.name}
8388
canary := newDeploymentControllerTestCanary(cc)
@@ -121,7 +126,7 @@ func newDeploymentFixture(dc deploymentConfigs) deploymentControllerFixture {
121126
logger: logger,
122127
flaggerClient: flaggerClient,
123128
kubeClient: kubeClient,
124-
}
129+
}, kubeClient
125130
}
126131

127132
func newDeploymentControllerTestConfigMap() *corev1.ConfigMap {
@@ -350,6 +355,7 @@ func newDeploymentControllerTestCanary(cc canaryConfigs) *flaggerv1.Canary {
350355
}
351356

352357
func newDeploymentControllerTest(dc deploymentConfigs) *appsv1.Deployment {
358+
var optional bool = false
353359
d := &appsv1.Deployment{
354360
TypeMeta: metav1.TypeMeta{APIVersion: appsv1.SchemeGroupVersion.String()},
355361
ObjectMeta: metav1.ObjectMeta{
@@ -473,6 +479,7 @@ func newDeploymentControllerTest(dc deploymentConfigs) *appsv1.Deployment {
473479
LocalObjectReference: corev1.LocalObjectReference{
474480
Name: "podinfo-config-vol",
475481
},
482+
Optional: &optional,
476483
},
477484
},
478485
},
@@ -481,6 +488,7 @@ func newDeploymentControllerTest(dc deploymentConfigs) *appsv1.Deployment {
481488
VolumeSource: corev1.VolumeSource{
482489
Secret: &corev1.SecretVolumeSource{
483490
SecretName: "podinfo-secret-vol",
491+
Optional: &optional,
484492
},
485493
},
486494
},

0 commit comments

Comments
 (0)