func validateIngressRules(ingressRules []extensions.IngressRule, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if len(ingressRules) == 0 { return append(allErrs, field.Required(fldPath, "")) } for i, ih := range ingressRules { if len(ih.Host) > 0 { if isIP := (net.ParseIP(ih.Host) != nil); isIP { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, "must be a DNS name, not an IP address")) } // TODO: Ports and ips are allowed in the host part of a url // according to RFC 3986, consider allowing them. if strings.Contains(ih.Host, "*") { for _, msg := range validation.IsWildcardDNS1123Subdomain(ih.Host) { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) } continue } for _, msg := range validation.IsDNS1123Subdomain(ih.Host) { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("host"), ih.Host, msg)) } } allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(0))...) } return allErrs }
// validatePodSecurityPolicySysctls validates the sysctls fields of PodSecurityPolicy. func validatePodSecurityPolicySysctls(fldPath *field.Path, sysctls []string) field.ErrorList { allErrs := field.ErrorList{} for i, s := range sysctls { if !IsValidSysctlPattern(string(s)) { allErrs = append( allErrs, field.Invalid(fldPath.Index(i), sysctls[i], fmt.Sprintf("must have at most %d characters and match regex %s", apivalidation.SysctlMaxLength, SysctlPatternFmt, )), ) } } return allErrs }
func validateIngressTLS(spec *extensions.IngressSpec, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} // TODO: Perform a more thorough validation of spec.TLS.Hosts that takes // the wildcard spec from RFC 6125 into account. for _, itls := range spec.TLS { for i, host := range itls.Hosts { if strings.Contains(host, "*") { for _, msg := range validation.IsWildcardDNS1123Subdomain(host) { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("hosts"), host, msg)) } continue } for _, msg := range validation.IsDNS1123Subdomain(host) { allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("hosts"), host, msg)) } } } return allErrs }
func AccumulateUniqueHostPorts(containers []v1.Container, accumulator *sets.String, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} for ci, ctr := range containers { idxPath := fldPath.Index(ci) portsPath := idxPath.Child("ports") for pi := range ctr.Ports { idxPath := portsPath.Index(pi) port := ctr.Ports[pi].HostPort if port == 0 { continue } str := fmt.Sprintf("%d/%s", port, ctr.Ports[pi].Protocol) if accumulator.Has(str) { allErrs = append(allErrs, field.Duplicate(idxPath.Child("hostPort"), str)) } else { accumulator.Insert(str) } } } 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()) { continue } 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...) } else { if !reflect.DeepEqual(a.Field(i).Interface(), b.Field(i).Interface()) { changes = append(changes, diff{path: path, a: a.Field(i).Interface(), b: b.Field(i).Interface()}) } } } 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: lA, lB := a.Len(), b.Len() l := lA if lB < lA { l = lB } if lA == lB && lA == 0 { if a.IsNil() != b.IsNil() { return []diff{{path: path, a: a.Interface(), b: b.Interface()}} } return nil } 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)}) } if len(diffs) == 0 { diffs = append(diffs, diff{path: path, a: a, b: b}) } return diffs case reflect.Map: if reflect.DeepEqual(a.Interface(), b.Interface()) { 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}) } if len(missing) == 0 { missing = append(missing, diff{path: path, a: a.Interface(), b: b.Interface()}) } 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()}} } }