Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 4f5d946

Browse files
committed
Add external secrets rule
Signed-off-by: Djordje Lukic <[email protected]>
1 parent b621499 commit 4f5d946

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package rules
2+
3+
import (
4+
"github.com/pkg/errors"
5+
)
6+
7+
type externalSecretsValidator struct {
8+
}
9+
10+
func NewExternalSecretsRule() Rule {
11+
return &externalSecretsValidator{}
12+
}
13+
14+
func (s *externalSecretsValidator) Collect(parent string, key string, value interface{}) {
15+
16+
}
17+
18+
func (s *externalSecretsValidator) Accept(parent string, key string) bool {
19+
return key == "secrets"
20+
}
21+
22+
func (s *externalSecretsValidator) Validate(cfgMap interface{}) []error {
23+
errs := []error{}
24+
if value, ok := cfgMap.(map[string]interface{}); ok {
25+
for secretName, secret := range value {
26+
if v1, ok := secret.(map[string]interface{}); ok {
27+
var hasExternal = false
28+
for key := range v1 {
29+
if key == "external" {
30+
hasExternal = true
31+
}
32+
}
33+
if !hasExternal {
34+
errs = append(errs, errors.Errorf(`secret %q should be external`, secretName))
35+
}
36+
}
37+
}
38+
}
39+
return errs
40+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package rules
2+
3+
import (
4+
"testing"
5+
6+
"gotest.tools/assert"
7+
)
8+
9+
func TestExternalSecrets(t *testing.T) {
10+
s := NewExternalSecretsRule()
11+
12+
t.Run("should accept secrets", func(t *testing.T) {
13+
// The secrets key is on the root path, that's why it doesn't
14+
// have a parent
15+
assert.Equal(t, s.Accept("", "secrets"), true)
16+
})
17+
18+
t.Run("should return nil if all secrets are external", func(t *testing.T) {
19+
input := map[string]interface{}{
20+
"my_secret": map[string]interface{}{
21+
"external": "true",
22+
},
23+
}
24+
25+
errs := s.Validate(input)
26+
assert.Equal(t, len(errs), 0)
27+
})
28+
29+
t.Run("should return error if no external secrets", func(t *testing.T) {
30+
input := map[string]interface{}{
31+
"my_secret": map[string]interface{}{
32+
"file": "./my_secret.txt",
33+
},
34+
}
35+
36+
errs := s.Validate(input)
37+
assert.Equal(t, len(errs), 1)
38+
assert.ErrorContains(t, errs[0], `secret "my_secret" should be external`)
39+
})
40+
41+
t.Run("should return all errors", func(t *testing.T) {
42+
input := map[string]interface{}{
43+
"my_secret": map[string]interface{}{
44+
"file": "./my_secret.txt",
45+
},
46+
"my_other_secret": map[string]interface{}{
47+
"file": "./my_secret.txt",
48+
},
49+
}
50+
51+
errs := s.Validate(input)
52+
assert.Equal(t, len(errs), 2)
53+
54+
assert.ErrorContains(t, errs[0], `secret "my_secret" should be external`)
55+
assert.ErrorContains(t, errs[1], `secret "my_other_secret" should be external`)
56+
})
57+
58+
}

internal/validator/rules/rule.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package rules
2+
3+
type Rule interface {
4+
Collect(path string, key string, value interface{})
5+
Accept(parent string, key string) bool
6+
Validate(value interface{}) []error
7+
}

0 commit comments

Comments
 (0)