in admission/admission.go [228:298]
func (a *Admission) ValidateNamespace(ctx context.Context, attrs api.Attributes) *admissionv1.AdmissionResponse {
// short-circuit on subresources
if attrs.GetSubresource() != "" {
return sharedAllowedResponse
}
obj, err := attrs.GetObject()
if err != nil {
klog.ErrorS(err, "failed to decode object")
return errorResponse(err, &apierrors.NewBadRequest("failed to decode object").ErrStatus)
}
namespace, ok := obj.(*corev1.Namespace)
if !ok {
klog.InfoS("failed to assert namespace type", "type", reflect.TypeOf(obj))
return errorResponse(nil, &apierrors.NewBadRequest("failed to decode namespace").ErrStatus)
}
newPolicy, newErrs := a.PolicyToEvaluate(namespace.Labels)
switch attrs.GetOperation() {
case admissionv1.Create:
// require valid labels on create
if len(newErrs) > 0 {
return invalidResponse(attrs, newErrs)
}
return sharedAllowedResponse
case admissionv1.Update:
// if update, check if policy labels changed
oldObj, err := attrs.GetOldObject()
if err != nil {
klog.ErrorS(err, "failed to decode old object")
return errorResponse(err, &apierrors.NewBadRequest("failed to decode old object").ErrStatus)
}
oldNamespace, ok := oldObj.(*corev1.Namespace)
if !ok {
klog.InfoS("failed to assert old namespace type", "type", reflect.TypeOf(oldObj))
return errorResponse(nil, &apierrors.NewBadRequest("failed to decode old namespace").ErrStatus)
}
oldPolicy, oldErrs := a.PolicyToEvaluate(oldNamespace.Labels)
// require valid labels on update if they have changed
if len(newErrs) > 0 && (len(oldErrs) == 0 || !reflect.DeepEqual(newErrs, oldErrs)) {
return invalidResponse(attrs, newErrs)
}
// Skip dry-running pods:
// * if the enforce policy is unchanged
// * if the new enforce policy is privileged
// * if the new enforce is the same version and level was relaxed
// * for exempt namespaces
if newPolicy.Enforce == oldPolicy.Enforce {
return sharedAllowedResponse
}
if newPolicy.Enforce.Level == api.LevelPrivileged {
return sharedAllowedResponse
}
if newPolicy.Enforce.Version == oldPolicy.Enforce.Version &&
api.CompareLevels(newPolicy.Enforce.Level, oldPolicy.Enforce.Level) < 1 {
return sharedAllowedResponse
}
if a.exemptNamespace(attrs.GetNamespace()) {
return sharedAllowedByNamespaceExemptionResponse
}
response := allowedResponse()
response.Warnings = a.EvaluatePodsInNamespace(ctx, namespace.Name, newPolicy.Enforce)
return response
default:
return sharedAllowedResponse
}
}