func ValidateLabelSelector(ps *unversioned.LabelSelector, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if ps == nil { return allErrs } allErrs = append(allErrs, ValidateLabels(ps.MatchLabels, fldPath.Child("matchLabels"))...) for i, expr := range ps.MatchExpressions { allErrs = append(allErrs, ValidateLabelSelectorRequirement(expr, fldPath.Child("matchExpressions").Index(i))...) } return allErrs }
func ValidateLabelSelectorRequirement(sr unversioned.LabelSelectorRequirement, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} switch sr.Operator { case unversioned.LabelSelectorOpIn, unversioned.LabelSelectorOpNotIn: if len(sr.Values) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("values"), "must be specified when `operator` is 'In' or 'NotIn'")) } case unversioned.LabelSelectorOpExists, unversioned.LabelSelectorOpDoesNotExist: if len(sr.Values) > 0 { allErrs = append(allErrs, field.Forbidden(fldPath.Child("values"), "may not be specified when `operator` is 'Exists' or 'DoesNotExist'")) } default: allErrs = append(allErrs, field.Invalid(fldPath.Child("operator"), sr.Operator, "not a valid selector operator")) } allErrs = append(allErrs, ValidateLabelName(sr.Key, fldPath.Child("key"))...) return allErrs }
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, reflect.Interface: 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; i < lA; i++ { diffs = append(diffs, diff{path: path.Index(i), a: a.Index(i), b: nil}) } for i := l; i < 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, objectReflectDiff(path.Key(fmt.Sprintf("%s", key.Interface())), a.MapIndex(key), b.MapIndex(key))...) 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()}} } }