Skip to content

Commit 4c224e9

Browse files
committed
feat: add env-value-from as opt-in check for #705
1 parent d579037 commit 4c224e9

File tree

2 files changed

+132
-4
lines changed

2 files changed

+132
-4
lines changed

pkg/templates/envvarvaluefrom/internal/params/params_test.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ import (
44
"testing"
55

66
"github.com/stretchr/testify/assert"
7+
"golang.stackrox.io/kube-linter/pkg/check"
8+
"golang.stackrox.io/kube-linter/pkg/diagnostic"
9+
"golang.stackrox.io/kube-linter/pkg/lintcontext"
710
)
811

912
func TestValidateParams(t *testing.T) {
1013
t.Run("InvalidRegex", func(t *testing.T) {
1114
p := Params{IgnoredSecrets: []string{"[invalid("}}
1215
err := p.Validate()
13-
// If Validate doesn't check regex, this will pass; otherwise, expect error
16+
// Current behavior: No validation, so no error
1417
if err == nil {
1518
t.Log("Warning: Validate does not check regex validity; consider adding regex validation")
1619
} else {
@@ -25,3 +28,45 @@ func TestValidateParams(t *testing.T) {
2528
assert.NoError(t, err)
2629
})
2730
}
31+
32+
func TestParseAndValidate(t *testing.T) {
33+
t.Run("InvalidDecode", func(t *testing.T) {
34+
// Simulate invalid map structure
35+
m := map[string]interface{}{"IgnoredSecrets": map[string]interface{}{"invalid": true}}
36+
_, err := ParseAndValidate(m)
37+
assert.Error(t, err) // Expect DecodeMapStructure to fail
38+
})
39+
40+
t.Run("ValidParse", func(t *testing.T) {
41+
m := map[string]interface{}{"IgnoredSecrets": []interface{}{"^valid$"}}
42+
p, err := ParseAndValidate(m)
43+
assert.NoError(t, err)
44+
assert.Equal(t, []string{"^valid$"}, p.(Params).IgnoredSecrets)
45+
})
46+
}
47+
48+
func TestWrapInstantiateFunc(t *testing.T) {
49+
t.Run("ValidWrap", func(t *testing.T) {
50+
f := func(p Params) (check.Func, error) {
51+
// check.Func is a function type, so we can return a function directly
52+
return func(lintCtx lintcontext.LintContext, object lintcontext.Object) []diagnostic.Diagnostic {
53+
return nil // Return empty slice instead of nil for consistency
54+
}, nil
55+
}
56+
wrapped := WrapInstantiateFunc(f)
57+
_, err := wrapped(Params{})
58+
assert.NoError(t, err)
59+
})
60+
61+
t.Run("InvalidType", func(t *testing.T) {
62+
f := func(p Params) (check.Func, error) {
63+
return func(lintCtx lintcontext.LintContext, object lintcontext.Object) []diagnostic.Diagnostic {
64+
return nil // Return empty slice instead of nil for consistency
65+
}, nil
66+
}
67+
wrapped := WrapInstantiateFunc(f)
68+
assert.Panics(t, func() {
69+
_, _ = wrapped("not-a-Params") // Expect panic due to type assertion failure
70+
})
71+
})
72+
}

pkg/templates/envvarvaluefrom/template_test.go

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,17 @@ func makeConfigMapSource(descriptor sourceReference) *coreV1.EnvVarSource {
6868
}
6969
}
7070

71-
func (s *EnVarValueFromTestSuite) addContainerWithEnvFromSecret(envRef envReference) { // Fix: Remove name parameter
71+
func (s *EnVarValueFromTestSuite) addContainerWithEnvFromSecret(envRef envReference) {
7272
var valueFrom *coreV1.EnvVarSource
7373
switch envRef.Kind {
7474
case "secret":
7575
valueFrom = makeSecretSource(envRef.Source)
7676
case "configmap":
7777
valueFrom = makeConfigMapSource(envRef.Source)
7878
default:
79-
s.Require().FailNow(fmt.Sprintf("Unknown source kind %s", envRef.Kind)) // Fix: Use s.Require().FailNow
79+
s.Require().FailNow(fmt.Sprintf("Unknown source kind %s", envRef.Kind))
8080
}
81-
s.ctx.AddContainerToDeployment(s.T(), targetDeploymentName, coreV1.Container{ // Fix: Hardcode targetDeploymentName
81+
s.ctx.AddContainerToDeployment(s.T(), targetDeploymentName, coreV1.Container{
8282
Name: "container",
8383
Env: []coreV1.EnvVar{
8484
{
@@ -342,3 +342,86 @@ func (s *EnVarValueFromTestSuite) TestKeysEmptyMap() {
342342
keys := Keys(emptyMap)
343343
s.Empty(keys)
344344
}
345+
346+
func (s *EnVarValueFromTestSuite) TestExtractRegexListInvalidConfigMaps() {
347+
p := params.Params{IgnoredConfigMaps: []string{"[invalid("}}
348+
_, err := extractRegexList(p.IgnoredConfigMaps)
349+
s.Error(err)
350+
s.Contains(err.Error(), "invalid regex [invalid(")
351+
}
352+
353+
func (s *EnVarValueFromTestSuite) TestUnknownKeyInSecretWithStringData() {
354+
s.ctx.AddMockDeployment(s.T(), targetDeploymentName)
355+
secret := &coreV1.Secret{
356+
ObjectMeta: metav1.ObjectMeta{Name: "test-secret"},
357+
StringData: map[string]string{"key1": "value"},
358+
}
359+
s.ctx.AddObject("test-secret", secret)
360+
s.addContainerWithEnvFromSecret(envReference{
361+
Name: "my-secret",
362+
Kind: "secret",
363+
Source: sourceReference{
364+
Name: "test-secret",
365+
Key: "unknown-key",
366+
Optional: pointers.Bool(false),
367+
},
368+
})
369+
s.Validate(s.ctx, []templates.TestCase{
370+
{
371+
Param: params.Params{},
372+
Diagnostics: map[string][]diagnostic.Diagnostic{
373+
targetDeploymentName: {{
374+
Message: "The container \"container\" is referring to an unknown key \"unknown-key\" in secret \"test-secret\"",
375+
}},
376+
},
377+
},
378+
})
379+
}
380+
381+
func (s *EnVarValueFromTestSuite) TestMultipleIgnoredSecrets() {
382+
s.ctx.AddMockDeployment(s.T(), targetDeploymentName)
383+
secret1 := &coreV1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "secret1"}, Data: map[string][]byte{"key": []byte("value")}}
384+
secret2 := &coreV1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "secret2"}, Data: map[string][]byte{"key": []byte("value")}}
385+
s.ctx.AddObject("secret1", secret1)
386+
s.ctx.AddObject("secret2", secret2)
387+
s.addContainerWithEnvFromSecret(envReference{
388+
Name: "my-secret",
389+
Kind: "secret",
390+
Source: sourceReference{
391+
Name: "secret1",
392+
Key: "key",
393+
Optional: pointers.Bool(false),
394+
},
395+
})
396+
s.Validate(s.ctx, []templates.TestCase{
397+
{
398+
Param: params.Params{IgnoredSecrets: []string{"^secret2$"}},
399+
Diagnostics: map[string][]diagnostic.Diagnostic{
400+
targetDeploymentName: {},
401+
},
402+
},
403+
})
404+
}
405+
406+
func (s *EnVarValueFromTestSuite) TestEmptyObjectList() {
407+
s.ctx.AddMockDeployment(s.T(), targetDeploymentName)
408+
s.addContainerWithEnvFromSecret(envReference{
409+
Name: "my-secret",
410+
Kind: "secret",
411+
Source: sourceReference{
412+
Name: "test-secret",
413+
Key: "key",
414+
Optional: pointers.Bool(false),
415+
},
416+
})
417+
s.Validate(s.ctx, []templates.TestCase{
418+
{
419+
Param: params.Params{},
420+
Diagnostics: map[string][]diagnostic.Diagnostic{
421+
targetDeploymentName: {{
422+
Message: "The container \"container\" is referring to an unknown secret \"test-secret\"",
423+
}},
424+
},
425+
},
426+
})
427+
}

0 commit comments

Comments
 (0)