mirror of https://github.com/k3s-io/k3s.git
Log policy name from pod security policy
parent
c38a704fb7
commit
241422879d
|
@ -84,6 +84,7 @@ var _ admission.MutationInterface = &PodSecurityPolicyPlugin{}
|
|||
var _ admission.ValidationInterface = &PodSecurityPolicyPlugin{}
|
||||
var _ genericadmissioninit.WantsAuthorizer = &PodSecurityPolicyPlugin{}
|
||||
var _ kubeapiserveradmission.WantsInternalKubeInformerFactory = &PodSecurityPolicyPlugin{}
|
||||
var auditKeyPrefix = strings.ToLower(PluginName) + "." + policy.GroupName + ".k8s.io"
|
||||
|
||||
// newPlugin creates a new PSP admission plugin.
|
||||
func newPlugin(strategyFactory psp.StrategyFactory, failOnNoPolicies bool) *PodSecurityPolicyPlugin {
|
||||
|
@ -136,6 +137,10 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes) error {
|
|||
pod.ObjectMeta.Annotations = map[string]string{}
|
||||
}
|
||||
pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation] = pspName
|
||||
key := auditKeyPrefix + "/" + "admit-policy"
|
||||
if err := a.AddAnnotation(key, pspName); err != nil {
|
||||
glog.Warningf("failed to set admission audit annotation %s to %s: %v", key, pspName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -154,11 +159,15 @@ func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes) error {
|
|||
pod := a.GetObject().(*api.Pod)
|
||||
|
||||
// compute the context. Mutation is not allowed. ValidatedPSPAnnotation is used as a hint to gain same speed-up.
|
||||
allowedPod, _, validationErrs, err := c.computeSecurityContext(a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation])
|
||||
allowedPod, pspName, validationErrs, err := c.computeSecurityContext(a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation])
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
if apiequality.Semantic.DeepEqual(pod, allowedPod) {
|
||||
key := auditKeyPrefix + "/" + "validate-policy"
|
||||
if err := a.AddAnnotation(key, pspName); err != nil {
|
||||
glog.Warningf("failed to set admission audit annotation %s to %s: %v", key, pspName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1798,11 +1798,24 @@ func testPSPAdmit(testCaseName string, psps []*policy.PodSecurityPolicy, pod *ka
|
|||
testPSPAdmitAdvanced(testCaseName, kadmission.Create, psps, nil, &user.DefaultInfo{}, pod, nil, shouldPassAdmit, shouldPassValidate, true, expectedPSP, t)
|
||||
}
|
||||
|
||||
// fakeAttributes decorate kadmission.Attributes. It's used to trace the added annotations.
|
||||
type fakeAttributes struct {
|
||||
kadmission.Attributes
|
||||
annotations map[string]string
|
||||
}
|
||||
|
||||
func (f fakeAttributes) AddAnnotation(k, v string) error {
|
||||
f.annotations[k] = v
|
||||
return f.Attributes.AddAnnotation(k, v)
|
||||
}
|
||||
|
||||
func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*policy.PodSecurityPolicy, authz authorizer.Authorizer, userInfo user.Info, pod, oldPod *kapi.Pod, shouldPassAdmit, shouldPassValidate bool, canMutate bool, expectedPSP string, t *testing.T) {
|
||||
originalPod := pod.DeepCopy()
|
||||
plugin := NewTestAdmission(psps, authz)
|
||||
|
||||
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, userInfo)
|
||||
annotations := make(map[string]string)
|
||||
attrs = &fakeAttributes{attrs, annotations}
|
||||
err := plugin.Admit(attrs)
|
||||
|
||||
if shouldPassAdmit && err != nil {
|
||||
|
@ -1832,11 +1845,27 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
|
|||
}
|
||||
|
||||
err = plugin.Validate(attrs)
|
||||
psp := ""
|
||||
if shouldPassAdmit && op == kadmission.Create {
|
||||
psp = expectedPSP
|
||||
}
|
||||
validateAuditAnnotation(t, testCaseName, annotations, "podsecuritypolicy.policy.k8s.io/admit-policy", psp)
|
||||
if shouldPassValidate && err != nil {
|
||||
t.Errorf("%s: expected no errors on Validate but received %v", testCaseName, err)
|
||||
} else if !shouldPassValidate && err == nil {
|
||||
t.Errorf("%s: expected errors on Validate but received none", testCaseName)
|
||||
}
|
||||
if shouldPassValidate {
|
||||
validateAuditAnnotation(t, testCaseName, annotations, "podsecuritypolicy.policy.k8s.io/validate-policy", expectedPSP)
|
||||
} else {
|
||||
validateAuditAnnotation(t, testCaseName, annotations, "podsecuritypolicy.policy.k8s.io/validate-policy", "")
|
||||
}
|
||||
}
|
||||
|
||||
func validateAuditAnnotation(t *testing.T, testCaseName string, annotations map[string]string, key, value string) {
|
||||
if annotations[key] != value {
|
||||
t.Errorf("%s: expected to have annotations[%s] set to %q, got %q", testCaseName, key, value, annotations[key])
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssignSecurityContext(t *testing.T) {
|
||||
|
|
|
@ -97,6 +97,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||
trace.Step("Conversion done")
|
||||
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer)
|
||||
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
|
|
|
@ -56,6 +56,8 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
|
|||
}
|
||||
ctx := req.Context()
|
||||
ctx = request.WithNamespace(ctx, namespace)
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
|
||||
options := &metav1.DeleteOptions{}
|
||||
if allowsOptions {
|
||||
|
@ -188,6 +190,8 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||
|
||||
ctx := req.Context()
|
||||
ctx = request.WithNamespace(ctx, namespace)
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
|
||||
if admit != nil && admit.Handles(admission.Delete) {
|
||||
userInfo, _ := request.UserFrom(ctx)
|
||||
|
|
|
@ -89,6 +89,8 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface
|
|||
}
|
||||
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
|
||||
audit.LogRequestPatch(ae, patchJS)
|
||||
trace.Step("Recorded the audit event")
|
||||
|
||||
|
|
|
@ -103,6 +103,9 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi
|
|||
}
|
||||
ctx := req.Context()
|
||||
ctx = request.WithNamespace(ctx, namespace)
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
|
||||
opts, subpath, subpathKey := connecter.NewConnectOptions()
|
||||
if err := getRequestOptions(req, scope, opts, subpath, subpathKey, isSubresource); err != nil {
|
||||
err = errors.NewBadRequest(err.Error())
|
||||
|
|
|
@ -86,6 +86,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||
|
||||
ae := request.AuditEventFrom(ctx)
|
||||
audit.LogRequestObject(ae, obj, scope.Resource, scope.Subresource, scope.Serializer)
|
||||
admit = admission.WithAudit(admit, ae)
|
||||
|
||||
if err := checkName(obj, name, namespace, scope.Namer); err != nil {
|
||||
scope.err(err, w, req)
|
||||
|
|
Loading…
Reference in New Issue