func ValidatePodSecurityPolicySpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if p := annotations[apparmor.DefaultProfileAnnotationKey]; p != "" { if err := apparmor.ValidateProfileFormat(p); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Key(apparmor.DefaultProfileAnnotationKey), p, err.Error())) } } if allowed := annotations[apparmor.AllowedProfilesAnnotationKey]; allowed != "" { for _, p := range strings.Split(allowed, ",") { if err := apparmor.ValidateProfileFormat(p); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Key(apparmor.AllowedProfilesAnnotationKey), allowed, err.Error())) } } } sysctlAnnotation := annotations[extensions.SysctlsPodSecurityPolicyAnnotationKey] sysctlFldPath := fldPath.Key(extensions.SysctlsPodSecurityPolicyAnnotationKey) sysctls, err := extensions.SysctlsFromPodSecurityPolicyAnnotation(sysctlAnnotation) if err != nil { allErrs = append(allErrs, field.Invalid(sysctlFldPath, sysctlAnnotation, err.Error())) } else { allErrs = append(allErrs, validatePodSecurityPolicySysctls(sysctlFldPath, sysctls)...) } if p := annotations[seccomp.DefaultProfileAnnotationKey]; p != "" { allErrs = append(allErrs, apivalidation.ValidateSeccompProfile(p, fldPath.Key(seccomp.DefaultProfileAnnotationKey))...) } if allowed := annotations[seccomp.AllowedProfilesAnnotationKey]; allowed != "" { for _, p := range strings.Split(allowed, ",") { allErrs = append(allErrs, apivalidation.ValidateSeccompProfile(p, fldPath.Key(seccomp.AllowedProfilesAnnotationKey))...) } } return allErrs }
func ValidateNodeSelector(nodeSelector map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for k, v := range nodeSelector { _, err := labelselector.Parse(fmt.Sprintf("%s=%s", k, v)) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Key(k), nodeSelector[k], "must be a valid node selector")) } } return allErrs }
func ValidateAdmissionPluginConfig(pluginConfig map[string]api.AdmissionPluginConfig, fieldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for name, config := range pluginConfig { if len(config.Location) > 0 && config.Configuration != nil { allErrs = append(allErrs, field.Invalid(fieldPath.Key(name), "", "cannot specify both location and embedded config")) } if len(config.Location) == 0 && config.Configuration == nil { allErrs = append(allErrs, field.Invalid(fieldPath.Key(name), "", "must specify either a location or an embedded config")) } } return allErrs }
func ValidateAPIServerExtendedArguments(config api.ExtendedArguments, fldPath *field.Path) ValidationResults { validationResults := ValidationResults{} validationResults.AddErrors(ValidateExtendedArguments(config, apiserveroptions.NewAPIServer().AddFlags, fldPath)...) if len(config["admission-control"]) > 0 { validationResults.AddWarnings(field.Invalid(fldPath.Key("admission-control"), config["admission-control"], "specified admission ordering is being phased out. Convert to DefaultAdmissionConfig in admissionConfig.pluginConfig.")) } if len(config["admission-control-config-file"]) > 0 { validationResults.AddWarnings(field.Invalid(fldPath.Key("admission-control-config-file"), config["admission-control-config-file"], "specify a single admission control config file is being phased out. Convert to admissionConfig.pluginConfig, one file per plugin.")) } return validationResults }
func ValidatePodSecurityPolicySpecificAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if p := annotations[apparmor.DefaultProfileAnnotationKey]; p != "" { if err := apparmor.ValidateProfileFormat(p); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Key(apparmor.DefaultProfileAnnotationKey), p, err.Error())) } } if allowed := annotations[apparmor.AllowedProfilesAnnotationKey]; allowed != "" { for _, p := range strings.Split(allowed, ",") { if err := apparmor.ValidateProfileFormat(p); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Key(apparmor.AllowedProfilesAnnotationKey), allowed, err.Error())) } } } return allErrs }
// Ensures that `nil` can be passed to validation functions validating top-level objects func TestNilPath(t *testing.T) { var nilPath *field.Path = nil if s := nilPath.String(); s != "" { t.Errorf("Unexpected nil path: %q", s) } child := nilPath.Child("child") if s := child.String(); s != "child" { t.Errorf("Unexpected child path: %q", s) } key := nilPath.Key("key") if s := key.String(); s != "[key]" { t.Errorf("Unexpected key path: %q", s) } index := nilPath.Index(1) if s := index.String(); s != "[1]" { t.Errorf("Unexpected index path: %q", s) } }
func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff { switch a.Type().Kind() { case reflect.Struct: var changes []diff for i := 0; i < a.Type().NumField(); i++ { if !public(a.Type().Field(i).Name) { if reflect.DeepEqual(a.Interface(), b.Interface()) { return nil } return []diff{{path: path, a: fmt.Sprintf("%#v", a), b: fmt.Sprintf("%#v", b)}} } if sub := objectReflectDiff(path.Child(a.Type().Field(i).Name), a.Field(i), b.Field(i)); len(sub) > 0 { changes = append(changes, sub...) } } return changes case reflect.Ptr: if a.IsNil() || b.IsNil() { switch { case a.IsNil() && b.IsNil(): return nil case a.IsNil(): return []diff{{path: path, a: nil, b: b.Interface()}} default: return []diff{{path: path, a: a.Interface(), b: nil}} } } return objectReflectDiff(path, a.Elem(), b.Elem()) case reflect.Chan: if !reflect.DeepEqual(a.Interface(), b.Interface()) { return []diff{{path: path, a: a.Interface(), b: b.Interface()}} } return nil case reflect.Slice: if reflect.DeepEqual(a, b) { return nil } lA, lB := a.Len(), b.Len() l := lA if lB < lA { l = lB } for i := 0; i < l; i++ { if !reflect.DeepEqual(a.Index(i), b.Index(i)) { return objectReflectDiff(path.Index(i), a.Index(i), b.Index(i)) } } var diffs []diff for i := l; l < lA; i++ { diffs = append(diffs, diff{path: path.Index(i), a: a.Index(i), b: nil}) } for i := l; l < lB; i++ { diffs = append(diffs, diff{path: path.Index(i), a: nil, b: b.Index(i)}) } return diffs case reflect.Map: if reflect.DeepEqual(a, b) { return nil } aKeys := make(map[interface{}]interface{}) for _, key := range a.MapKeys() { aKeys[key.Interface()] = a.MapIndex(key).Interface() } var missing []diff for _, key := range b.MapKeys() { if _, ok := aKeys[key.Interface()]; ok { delete(aKeys, key.Interface()) if reflect.DeepEqual(a.MapIndex(key).Interface(), b.MapIndex(key).Interface()) { continue } missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key.Interface())), a: a.MapIndex(key).Interface(), b: b.MapIndex(key).Interface()}) continue } missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key.Interface())), a: nil, b: b.MapIndex(key).Interface()}) } for key, value := range aKeys { missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key)), a: value, b: nil}) } sort.Sort(orderedDiffs(missing)) return missing default: if reflect.DeepEqual(a.Interface(), b.Interface()) { return nil } if !a.CanInterface() { return []diff{{path: path, a: fmt.Sprintf("%#v", a), b: fmt.Sprintf("%#v", b)}} } return []diff{{path: path, a: a.Interface(), b: b.Interface()}} } }