Skip to content

Commit

Permalink
Merge pull request #103452 from njuptlzf/ps-ValidatePodController-ut
Browse files Browse the repository at this point in the history
[test-only][PodSecurity] Add test coverage for pod-template-containing objects
  • Loading branch information
k8s-ci-robot committed Jul 10, 2021
2 parents a26c39e + 2b88dc3 commit b2bf3d7
Showing 1 changed file with 183 additions and 0 deletions.
183 changes: 183 additions & 0 deletions staging/src/k8s.io/pod-security-admission/admission/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ func (t *testEvaluator) EvaluatePod(lv api.LevelVersion, meta *metav1.ObjectMeta
}
}

type testNamespaceGetter struct {
ns *corev1.Namespace
}

func (t *testNamespaceGetter) GetNamespace(ctx context.Context, name string) (*corev1.Namespace, error) {
return t.ns, nil
}

type testPodLister struct {
called bool
pods []*corev1.Pod
Expand Down Expand Up @@ -457,3 +465,178 @@ func TestValidateNamespace(t *testing.T) {
})
}
}

func TestValidatePodController(t *testing.T) {
testName, testNamespace := "testname", "default"
objMetadata := metav1.ObjectMeta{Name: testName, Namespace: testNamespace, Labels: map[string]string{"foo": "bar"}}
// One of the pod-template objects
goodDeploy := appsv1.Deployment{
ObjectMeta: objMetadata,
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
Template: corev1.PodTemplateSpec{
ObjectMeta: objMetadata,
Spec: corev1.PodSpec{
RuntimeClassName: pointer.String("containerd"),
},
},
},
}
badDeploy := appsv1.Deployment{
ObjectMeta: objMetadata,
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
Template: corev1.PodTemplateSpec{
ObjectMeta: objMetadata,
Spec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{
// out of allowed sysctls to return auditAnnotation or warning
Sysctls: []corev1.Sysctl{{Name: "unknown", Value: "unknown"}},
},
RuntimeClassName: pointer.String("containerd"),
},
},
},
}

// Ensure that under the baseline policy,
// the pod-template object of all tests returns correct information or is exempted
nsLabels := map[string]string{
api.EnforceLevelLabel: string(api.LevelBaseline),
api.WarnLevelLabel: string(api.LevelBaseline),
api.AuditLevelLabel: string(api.LevelBaseline),
}

testCases := []struct {
desc string
exemptNamespaces []string
exemptRuntimeClasses []string
exemptUsers []string
// request subresource
subresource string
// for create
newObject runtime.Object
// for update
oldObject runtime.Object
gvr schema.GroupVersionResource

expectWarnings []string
expectAuditAnnotations map[string]string
}{
{
desc: "subresource(status) updates don't produce warnings",
subresource: "status",
newObject: &badDeploy,
oldObject: &goodDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
},
{
desc: "namespace in exemptNamespaces will be exempted",
newObject: &badDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
exemptNamespaces: []string{testNamespace},
},
{
desc: "runtimeClass in exemptRuntimeClasses will be exempted",
newObject: &badDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
exemptRuntimeClasses: []string{"containerd"},
},
{
desc: "user in exemptUsers will be exempted",
newObject: &badDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
exemptUsers: []string{"testuser"},
},
{
desc: "podMetadata == nil && podSpec == nil will skip verification",
newObject: &corev1.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo-rc"}},
gvr: schema.GroupVersionResource{Group: "", Version: "v1", Resource: "replicationcontrollers"},
},
{
desc: "good deploy creates and produce nothing",
newObject: &goodDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
expectAuditAnnotations: map[string]string{},
},
{
desc: "bad deploy creates produce correct user-visible warnings and correct auditAnnotations",
newObject: &badDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
expectAuditAnnotations: map[string]string{"audit": "forbidden sysctls (unknown)"},
expectWarnings: []string{"would violate \"latest\" version of \"baseline\" PodSecurity profile: forbidden sysctls (unknown)"},
},
{
desc: "bad spec updates don't block on enforce failures and returns correct information",
newObject: &badDeploy,
oldObject: &goodDeploy,
gvr: schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
expectAuditAnnotations: map[string]string{"audit": "forbidden sysctls (unknown)"},
expectWarnings: []string{"would violate \"latest\" version of \"baseline\" PodSecurity profile: forbidden sysctls (unknown)"},
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
var operation = admissionv1.Create
if tc.oldObject != nil {
operation = admissionv1.Update
}

attrs := &AttributesRecord{
testName,
testNamespace,
tc.gvr,
tc.subresource,
operation,
tc.newObject,
tc.oldObject,
"testuser",
}

defaultPolicy := api.Policy{
Enforce: api.LevelVersion{Level: api.LevelPrivileged, Version: api.LatestVersion()},
Audit: api.LevelVersion{Level: api.LevelPrivileged, Version: api.LatestVersion()},
Warn: api.LevelVersion{Level: api.LevelPrivileged, Version: api.LatestVersion()},
}

podLister := &testPodLister{}
evaluator, err := policy.NewEvaluator(policy.DefaultChecks())
assert.NoError(t, err)
nsGetter := &testNamespaceGetter{
ns: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: testName,
Namespace: testNamespace,
Labels: nsLabels}},
}
PodSpecExtractor := &DefaultPodSpecExtractor{}
a := &Admission{
PodLister: podLister,
Evaluator: evaluator,
PodSpecExtractor: PodSpecExtractor,
Configuration: &admissionapi.PodSecurityConfiguration{
Exemptions: admissionapi.PodSecurityExemptions{
Namespaces: tc.exemptNamespaces,
RuntimeClasses: tc.exemptRuntimeClasses,
Usernames: tc.exemptUsers,
},
},
defaultPolicy: defaultPolicy,
NamespaceGetter: nsGetter,
}

result := a.ValidatePodController(context.TODO(), attrs)
// podContorller will not return an error due to correct evaluation
resultError := ""
if result.Result != nil {
resultError = result.Result.Message
}

assert.Equal(t, true, result.Allowed)
assert.Empty(t, resultError)
assert.Equal(t, tc.expectAuditAnnotations, result.AuditAnnotations, "unexpected AuditAnnotations")
assert.Equal(t, tc.expectWarnings, result.Warnings, "unexpected Warnings")
})
}
}

0 comments on commit b2bf3d7

Please sign in to comment.