1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

chore: improve unit tests in cli (#8304)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-09-07 11:16:26 +02:00 committed by GitHub
parent 5a83c19be9
commit a4b3388bda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 274 additions and 12 deletions

View file

@ -0,0 +1,55 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: limit-configmap-for-sa
annotations:
policies.kyverno.io/title: Limit ConfigMap to ServiceAccounts for a User
policies.kyverno.io/category: Other
policies.kyverno.io/severity: medium
kyverno.io/kyverno-version: 1.6.0
kyverno.io/kubernetes-version: "1.20-1.23"
policies.kyverno.io/subject: ConfigMap, ServiceAccount
policies.kyverno.io/description: This policy shows how to restrict certain operations on specific ConfigMaps by ServiceAccounts.
spec:
background: false
validationFailureAction: audit
rules:
- name: limit-configmap-for-sa-developer
match:
any:
- resources:
kinds:
- ConfigMap
subjects:
- kind: ServiceAccount
name: developer
namespace: kube-system
- resources:
kinds:
- ConfigMap
subjects:
- kind: ServiceAccount
name: another-developer
namespace: another-namespace
preconditions:
all:
- key: "{{request.object.metadata.namespace}}"
operator: In
value:
- "any-namespace"
- "another-namespace"
- key: "{{request.object.metadata.name}}"
operator: In
value:
- "any-configmap-name-good"
- "another-configmap-name"
validate:
message: "{{request.object.metadata.namespace}}/{{request.object.kind}}/{{request.object.metadata.name}} resource is protected. Admin or allowed users can change the resource"
deny:
conditions:
all:
- key: "{{request.operation}}"
operator: "In"
value:
- "UPDATE"
- "CREATE"

View file

@ -0,0 +1,3 @@
globalValues:
foo: bar
baz: jee

View file

@ -268,7 +268,7 @@ func (c *ApplyCommandConfig) applyPolicytoResource(
}
}
kindOnwhichPolicyIsApplied := common.GetKindsFromPolicy(pol, vars.Subresources(), dClient)
resourceValues, err := vars.CheckVariableForPolicy(pol.GetName(), resource.GetName(), resource.GetKind(), kindOnwhichPolicyIsApplied, matches...)
resourceValues, err := vars.ComputeVariables(pol.GetName(), resource.GetName(), resource.GetKind(), kindOnwhichPolicyIsApplied, matches...)
if err != nil {
return &rc, resources, skipInvalidPolicies, responses, sanitizederror.NewWithError(fmt.Sprintf("policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag", pol.GetName(), resource.GetName()), err)
}

View file

@ -140,7 +140,7 @@ func runTest(openApiManager openapi.Manager, testCase test.TestCase, auditWarn b
kindOnwhichPolicyIsApplied := common.GetKindsFromPolicy(pol, vars.Subresources(), dClient)
for _, resource := range uniques {
resourceValues, err := vars.CheckVariableForPolicy(pol.GetName(), resource.GetName(), resource.GetKind(), kindOnwhichPolicyIsApplied, matches...)
resourceValues, err := vars.ComputeVariables(pol.GetName(), resource.GetName(), resource.GetKind(), kindOnwhichPolicyIsApplied, matches...)
if err != nil {
message := fmt.Sprintf(
"policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag",

View file

@ -0,0 +1,9 @@
package log
import "testing"
func TestConfigure(t *testing.T) {
if err := Configure(); (err != nil) != false {
t.Errorf("Configure() error = %v, wantErr %v", err, false)
}
}

View file

@ -0,0 +1,61 @@
package policy
import (
"reflect"
"testing"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/stretchr/testify/assert"
)
func TestExtractVariables(t *testing.T) {
loadPolicy := func(path string) kyvernov1.PolicyInterface {
t.Helper()
policies, _, err := Load(nil, "", path)
assert.NoError(t, err)
assert.Equal(t, len(policies), 1)
return policies[0]
}
tests := []struct {
name string
policy kyvernov1.PolicyInterface
want []string
wantErr bool
}{{
name: "nil",
policy: nil,
want: nil,
wantErr: false,
}, {
name: "cpol-pod-requirements",
policy: loadPolicy("../_testdata/policies/cpol-pod-requirements.yaml"),
want: nil,
wantErr: false,
}, {
name: "cpol-limit-configmap-for-sa",
policy: loadPolicy("../_testdata/policies/cpol-limit-configmap-for-sa.yaml"),
want: []string{
"{{request.object.metadata.namespace}}",
"{{request.object.metadata.name}}",
"{{request.object.metadata.namespace}}",
"{{request.object.kind}}",
"{{request.object.metadata.name}}",
"{{request.operation}}",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ExtractVariables(tt.policy)
if (err != nil) != tt.wantErr {
t.Errorf("ExtractVariables() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ExtractVariables() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -42,8 +42,8 @@ func Test_readFile(t *testing.T) {
wantErr: false,
}, {
name: "valid",
filepath: "../_testdata/values/valid.yaml",
want: mustReadFile("../_testdata/values/valid.yaml"),
filepath: "../_testdata/values/limit-configmap-for-sa.yaml",
want: mustReadFile("../_testdata/values/limit-configmap-for-sa.yaml"),
wantErr: false,
}, {
name: "empty (billy)",
@ -107,7 +107,7 @@ func TestLoad(t *testing.T) {
wantErr: true,
}, {
name: "valid",
filepath: "../_testdata/values/valid.yaml",
filepath: "../_testdata/values/limit-configmap-for-sa.yaml",
want: &valuesapi.Values{
NamespaceSelectors: []valuesapi.NamespaceSelector{{
Name: "test1",

View file

@ -89,7 +89,7 @@ func TestNew(t *testing.T) {
name: "values file",
fs: nil,
resourcePath: "",
path: "../_testdata/values/valid.yaml",
path: "../_testdata/values/limit-configmap-for-sa.yaml",
vals: nil,
vars: nil,
want: &Variables{
@ -121,7 +121,7 @@ func TestNew(t *testing.T) {
name: "values file and vars",
fs: nil,
resourcePath: "",
path: "../_testdata/values/valid.yaml",
path: "../_testdata/values/limit-configmap-for-sa.yaml",
vals: nil,
vars: []string{
"foo=bar",
@ -167,7 +167,7 @@ func TestNew(t *testing.T) {
name: "values and values file",
fs: nil,
resourcePath: "",
path: "../_testdata/values/valid.yaml",
path: "../_testdata/values/limit-configmap-for-sa.yaml",
vals: &valuesapi.Values{
GlobalValues: map[string]string{
"bar": "baz",

View file

@ -55,7 +55,7 @@ func (v Variables) NamespaceSelectors() map[string]Labels {
return out
}
func (v Variables) CheckVariableForPolicy(policy, resource, kind string, kindMap sets.Set[string], variables ...string) (map[string]interface{}, error) {
func (v Variables) ComputeVariables(policy, resource, kind string, kindMap sets.Set[string], variables ...string) (map[string]interface{}, error) {
resourceValues := map[string]interface{}{}
// first apply global values
if v.values != nil {

View file

@ -7,6 +7,7 @@ import (
valuesapi "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apis/values"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/values"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/sets"
)
func TestVariables_HasVariables(t *testing.T) {
@ -93,7 +94,7 @@ func TestVariables_Subresources(t *testing.T) {
}
func TestVariables_NamespaceSelectors(t *testing.T) {
vals, err := values.Load(nil, "../_testdata/values/valid.yaml")
vals, err := values.Load(nil, "../_testdata/values/limit-configmap-for-sa.yaml")
assert.NoError(t, err)
tests := []struct {
name string
@ -134,7 +135,7 @@ func TestVariables_NamespaceSelectors(t *testing.T) {
}
func TestVariables_SetInStore(t *testing.T) {
vals, err := values.Load(nil, "../_testdata/values/valid.yaml")
vals, err := values.Load(nil, "../_testdata/values/limit-configmap-for-sa.yaml")
assert.NoError(t, err)
vals.Policies = append(vals.Policies, valuesapi.Policy{
Name: "limit-configmap-for-sa",
@ -177,7 +178,7 @@ func TestVariables_SetInStore(t *testing.T) {
}
func TestVariables_HasPolicyVariables(t *testing.T) {
vals, err := values.Load(nil, "../_testdata/values/valid.yaml")
vals, err := values.Load(nil, "../_testdata/values/limit-configmap-for-sa.yaml")
assert.NoError(t, err)
vals.Policies = append(vals.Policies, valuesapi.Policy{
Name: "limit-configmap-for-sa",
@ -234,3 +235,136 @@ func TestVariables_HasPolicyVariables(t *testing.T) {
})
}
}
func TestVariables_ComputeVariables(t *testing.T) {
loadValues := func(path string) *valuesapi.Values {
t.Helper()
vals, err := values.Load(nil, path)
assert.NoError(t, err)
return vals
}
type fields struct {
values *valuesapi.Values
variables map[string]string
}
type args struct {
policy string
resource string
kind string
kindMap sets.Set[string]
variables []string
}
tests := []struct {
name string
fields fields
args args
want map[string]interface{}
wantErr bool
}{
{
name: "nil",
args: args{
"limit-configmap-for-sa",
"any-configmap-name-good",
"ConfigMap",
nil,
nil,
},
want: map[string]interface{}{
"request.operation": "CREATE",
},
wantErr: false,
},
{
name: "values",
fields: fields{
loadValues("../_testdata/values/limit-configmap-for-sa.yaml"),
nil,
},
args: args{
"limit-configmap-for-sa",
"any-configmap-name-good",
"ConfigMap",
nil,
nil,
},
want: map[string]interface{}{
"request.operation": "UPDATE",
},
wantErr: false,
}, {
name: "values",
fields: fields{
loadValues("../_testdata/values/limit-configmap-for-sa.yaml"),
nil,
},
args: args{
"test",
"any-configmap-name-good",
"ConfigMap",
nil,
nil,
},
want: map[string]interface{}{
"request.operation": "CREATE",
},
wantErr: false,
}, {
name: "values",
fields: fields{
loadValues("../_testdata/values/global-values.yaml"),
nil,
},
args: args{
"test",
"any-configmap-name-good",
"ConfigMap",
nil,
nil,
},
want: map[string]interface{}{
"baz": "jee",
"foo": "bar",
"request.operation": "CREATE",
},
wantErr: false,
}, {
name: "values and variables",
fields: fields{
loadValues("../_testdata/values/global-values.yaml"),
map[string]string{
"request.operation": "DELETE",
},
},
args: args{
"test",
"any-configmap-name-good",
"ConfigMap",
nil,
nil,
},
want: map[string]interface{}{
"baz": "jee",
"foo": "bar",
"request.operation": "DELETE",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v := Variables{
values: tt.fields.values,
variables: tt.fields.variables,
}
got, err := v.ComputeVariables(tt.args.policy, tt.args.resource, tt.args.kind, tt.args.kindMap, tt.args.variables...)
if (err != nil) != tt.wantErr {
t.Errorf("Variables.ComputeVariables() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Variables.ComputeVariables() = %v, want %v", got, tt.want)
}
})
}
}