Skip to content

Commit

Permalink
feat(conftest): assert that resource kinds are defined for policies
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>
  • Loading branch information
danielpacak committed Oct 29, 2021
1 parent 5794ab3 commit b430ecc
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 27 deletions.
10 changes: 9 additions & 1 deletion pkg/plugin/conftest/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ func (c Config) GetLibraries() map[string]string {
func (c Config) GetPoliciesByKind(kind string) (map[string]string, error) {
policies := make(map[string]string)
for key, value := range c.Data {
if strings.HasSuffix(key, keySuffixRego) && strings.HasPrefix(key, keyPrefixPolicy) {
// Check if kinds were defined for this policy
kindsKey := strings.TrimSuffix(key, keySuffixRego) + keySuffixKinds
if _, ok := c.Data[kindsKey]; !ok {
return nil, fmt.Errorf("kinds not defined for policy: %s", key)
}
}

if !strings.HasSuffix(key, keySuffixKinds) {
continue
}
Expand All @@ -91,7 +99,7 @@ func (c Config) GetPoliciesByKind(kind string) (map[string]string, error) {

policies[policyKey], ok = c.Data[policyKey]
if !ok {
return nil, fmt.Errorf("policy not found: %s", policyKey)
return nil, fmt.Errorf("expected policy not found: %s", policyKey)
}
}
}
Expand Down
97 changes: 71 additions & 26 deletions pkg/plugin/conftest/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,80 @@ var (
)

func TestConfig_GetPoliciesByKind(t *testing.T) {
g := NewGomegaWithT(t)
config := conftest.Config{
PluginConfig: starboard.PluginConfig{
Data: map[string]string{
"conftest.imageRef": "openpolicyagent/conftest:v0.23.0",

"conftest.resources.requests.cpu": "50m",
"conftest.resources.requests.memory": "50M",
"conftest.resources.limits.cpu": "300m",
"conftest.resources.limits.memory": "300M",
t.Run("Should return error when kinds are not defined for policy", func(t *testing.T) {
g := NewGomegaWithT(t)
config := conftest.Config{
PluginConfig: starboard.PluginConfig{
Data: map[string]string{
"conftest.library.kubernetes.rego": "<REGO_A>",
"conftest.library.utils.rego": "<REGO_B>",
"conftest.policy.access_to_host_pid.rego": "<REGO_C>",
},
},
}
_, err := config.GetPoliciesByKind("Pod")
g.Expect(err).To(MatchError("kinds not defined for policy: conftest.policy.access_to_host_pid.rego"))
})

t.Run("Should return error when policy is not found", func(t *testing.T) {
g := NewGomegaWithT(t)
config := conftest.Config{
PluginConfig: starboard.PluginConfig{
Data: map[string]string{
"conftest.policy.access_to_host_pid.kinds": "Workload",
},
},
}
_, err := config.GetPoliciesByKind("Pod")
g.Expect(err).To(MatchError("expected policy not found: conftest.policy.access_to_host_pid.rego"))
})

"conftest.library.kubernetes.rego": "<REGO_A>",
"conftest.library.utils.rego": "<REGO_B>",
"conftest.policy.access_to_host_pid.rego": "<REGO_C>",
"conftest.policy.cpu_not_limited.rego": "<REGO_D>",
"conftest.policy.access_to_host_pid.kinds": "Pod,ReplicaSet",
"conftest.policy.cpu_not_limited.kinds": "Workload",

// This one should be skipped (no .rego suffix)
"conftest.policy.privileged": "<REGO_E>",
// This one should be skipped (no conftest.policy. prefix)
"foo": "bar",
t.Run("Should return policies as Rego modules", func(t *testing.T) {

g := NewGomegaWithT(t)
config := conftest.Config{
PluginConfig: starboard.PluginConfig{
Data: map[string]string{
"conftest.imageRef": "openpolicyagent/conftest:v0.23.0",

"conftest.resources.requests.cpu": "50m",
"conftest.resources.requests.memory": "50M",
"conftest.resources.limits.cpu": "300m",
"conftest.resources.limits.memory": "300M",

"conftest.library.kubernetes.rego": "<REGO_A>",
"conftest.library.utils.rego": "<REGO_B>",
"conftest.policy.access_to_host_pid.rego": "<REGO_C>",
"conftest.policy.cpu_not_limited.rego": "<REGO_D>",
"configmap_with_sensitive_data.rego": "<REGO_E>",
"configmap_with_secret_data.rego": "<REGO_F>",
"conftest.policy.object_without_recommended_labels.rego": "<REGO_G>",

"conftest.policy.access_to_host_pid.kinds": "Pod,ReplicaSet",
"conftest.policy.cpu_not_limited.kinds": "Workload",
"configmap_with_sensitive_data.kinds": "ConfigMap",
"configmap_with_secret_data.kinds": "ConfigMap",
"conftest.policy.object_without_recommended_labels.kinds": "*",

// This one should be skipped (no .rego suffix)
"conftest.policy.privileged": "<REGO_E>",
// This one should be skipped (no conftest.policy. prefix)
"foo": "bar",
},
},
},
}
g.Expect(config.GetPoliciesByKind("Pod")).To(Equal(map[string]string{
"conftest.policy.access_to_host_pid.rego": "<REGO_C>",
"conftest.policy.cpu_not_limited.rego": "<REGO_D>",
}))
}
g.Expect(config.GetPoliciesByKind("Pod")).To(Equal(map[string]string{
"conftest.policy.access_to_host_pid.rego": "<REGO_C>",
"conftest.policy.cpu_not_limited.rego": "<REGO_D>",
"conftest.policy.object_without_recommended_labels.rego": "<REGO_G>",
}))
g.Expect(config.GetPoliciesByKind("ConfigMap")).To(Equal(map[string]string{
"configmap_with_sensitive_data.rego": "<REGO_E>",
"configmap_with_secret_data.rego": "<REGO_F>",
"conftest.policy.object_without_recommended_labels.rego": "<REGO_G>",
}))
})
}

func TestConfig_GetResourceRequirements(t *testing.T) {
Expand Down

0 comments on commit b430ecc

Please sign in to comment.