func (s *mustMatchPatterns) validateAnnotation(pod *api.Pod, key string) field.ErrorList {
	allErrs := field.ErrorList{}

	fieldPath := field.NewPath("pod", "metadata", "annotations").Key(key)

	sysctls, err := api.SysctlsFromPodAnnotation(pod.Annotations[key])
	if err != nil {
		allErrs = append(allErrs, field.Invalid(fieldPath, pod.Annotations[key], err.Error()))
	}

	if len(sysctls) > 0 {
		if len(s.patterns) == 0 {
			allErrs = append(allErrs, field.Invalid(fieldPath, pod.Annotations[key], "sysctls are not allowed"))
		} else {
			for i, sysctl := range sysctls {
				allErrs = append(allErrs, s.ValidateSysctl(sysctl.Name, fieldPath.Index(i))...)
			}
		}
	}

	return allErrs
}
Example #2
0
// Admit checks that all sysctls given in a api.SysctlsPodAnnotationKey annotation
// are valid according to the whitelist.
func (w *patternWhitelist) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult {
	pod := attrs.Pod
	a := pod.Annotations[w.annotationKey]
	if a == "" {
		return lifecycle.PodAdmitResult{
			Admit: true,
		}
	}

	sysctls, err := api.SysctlsFromPodAnnotation(a)
	if err != nil {
		return lifecycle.PodAdmitResult{
			Admit:   false,
			Reason:  AnnotationInvalidReason,
			Message: fmt.Sprintf("invalid %s annotation: %v", w.annotationKey, err),
		}
	}

	var hostNet, hostIPC bool
	if pod.Spec.SecurityContext != nil {
		hostNet = pod.Spec.SecurityContext.HostNetwork
		hostIPC = pod.Spec.SecurityContext.HostIPC
	}
	for _, s := range sysctls {
		if err := w.validateSysctl(s.Name, hostNet, hostIPC); err != nil {
			return lifecycle.PodAdmitResult{
				Admit:   false,
				Reason:  ForbiddenReason,
				Message: fmt.Sprintf("forbidden sysctl: %v", err),
			}
		}
	}

	return lifecycle.PodAdmitResult{
		Admit: true,
	}
}