// ValidateService tests if required fields in the service are set. func ValidateService(service *api.Service) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName).Prefix("metadata")...) if !util.IsValidPortNum(service.Spec.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("spec.port", service.Spec.Port, portRangeErrorMsg)) } if len(service.Spec.Protocol) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("spec.protocol", service.Spec.Protocol)) } else if !supportedPortProtocols.Has(strings.ToUpper(string(service.Spec.Protocol))) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.protocol", service.Spec.Protocol)) } if service.Spec.Selector != nil { allErrs = append(allErrs, ValidateLabels(service.Spec.Selector, "spec.selector")...) } if service.Spec.SessionAffinity == "" { allErrs = append(allErrs, errs.NewFieldRequired("spec.sessionAffinity", service.Spec.SessionAffinity)) } else if !supportedSessionAffinityType.Has(string(service.Spec.SessionAffinity)) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.sessionAffinity", service.Spec.SessionAffinity)) } return allErrs }
// CreateObjects creates bulk of resources provided by items list. Each item must // be valid API type. It requires ObjectTyper to parse the Version and Kind and // RESTMapper to get the resource URI and REST client that knows how to create // given type func CreateObjects(typer runtime.ObjectTyper, mapper meta.RESTMapper, clientFor ClientFunc, objects []runtime.Object) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} for i, obj := range objects { version, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { reportError(&allErrors, i, errs.NewFieldInvalid("kind", obj)) continue } mapping, err := mapper.RESTMapping(version, kind) if err != nil { reportError(&allErrors, i, errs.NewFieldNotSupported("mapping", err)) continue } client, err := clientFor(mapping) if err != nil { reportError(&allErrors, i, errs.NewFieldNotSupported("client", obj)) continue } if err := CreateObject(client, mapping, obj); err != nil { reportError(&allErrors, i, *err) } } return allErrors.Prefix("Config") }
func validatePorts(ports []api.Port) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allNames := util.StringSet{} for i, port := range ports { pErrs := errs.ValidationErrorList{} if len(port.Name) > 0 { if len(port.Name) > util.DNS1123LabelMaxLength || !util.IsDNSLabel(port.Name) { pErrs = append(pErrs, errs.NewFieldInvalid("name", port.Name, dnsLabelErrorMsg)) } else if allNames.Has(port.Name) { pErrs = append(pErrs, errs.NewFieldDuplicate("name", port.Name)) } else { allNames.Insert(port.Name) } } if port.ContainerPort == 0 { pErrs = append(pErrs, errs.NewFieldInvalid("containerPort", port.ContainerPort, portRangeErrorMsg)) } else if !util.IsValidPortNum(port.ContainerPort) { pErrs = append(pErrs, errs.NewFieldInvalid("containerPort", port.ContainerPort, portRangeErrorMsg)) } if port.HostPort != 0 && !util.IsValidPortNum(port.HostPort) { pErrs = append(pErrs, errs.NewFieldInvalid("hostPort", port.HostPort, portRangeErrorMsg)) } if len(port.Protocol) == 0 { pErrs = append(pErrs, errs.NewFieldRequired("protocol", port.Protocol)) } else if !supportedPortProtocols.Has(strings.ToUpper(string(port.Protocol))) { pErrs = append(pErrs, errs.NewFieldNotSupported("protocol", port.Protocol)) } allErrs = append(allErrs, pErrs.PrefixIndex(i)...) } return allErrs }
// ValidateReplicationControllerSpec tests if required fields in the replication controller spec are set. func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} selector := labels.Set(spec.Selector).AsSelector() if selector.Empty() { allErrs = append(allErrs, errs.NewFieldRequired("selector")) } if spec.Replicas < 0 { allErrs = append(allErrs, errs.NewFieldInvalid("replicas", spec.Replicas, isNegativeErrorMsg)) } if spec.Template == nil { allErrs = append(allErrs, errs.NewFieldRequired("template")) } else { labels := labels.Set(spec.Template.Labels) if !selector.Matches(labels) { allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) } allErrs = append(allErrs, ValidatePodTemplateSpec(spec.Template, spec.Replicas).Prefix("template")...) // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { allErrs = append(allErrs, errs.NewFieldNotSupported("template.restartPolicy", spec.Template.Spec.RestartPolicy)) } } return allErrs }
func validatePorts(ports []api.Port) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allNames := util.StringSet{} for i := range ports { pErrs := errs.ValidationErrorList{} port := &ports[i] // so we can set default values if len(port.Name) > 0 { if len(port.Name) > 63 || !util.IsDNSLabel(port.Name) { pErrs = append(pErrs, errs.NewFieldInvalid("name", port.Name, "")) } else if allNames.Has(port.Name) { pErrs = append(pErrs, errs.NewFieldDuplicate("name", port.Name)) } else { allNames.Insert(port.Name) } } if port.ContainerPort == 0 { pErrs = append(pErrs, errs.NewFieldRequired("containerPort", port.ContainerPort)) } else if !util.IsValidPortNum(port.ContainerPort) { pErrs = append(pErrs, errs.NewFieldInvalid("containerPort", port.ContainerPort, "")) } if port.HostPort != 0 && !util.IsValidPortNum(port.HostPort) { pErrs = append(pErrs, errs.NewFieldInvalid("hostPort", port.HostPort, "")) } if len(port.Protocol) == 0 { port.Protocol = "TCP" } else if !supportedPortProtocols.Has(strings.ToUpper(string(port.Protocol))) { pErrs = append(pErrs, errs.NewFieldNotSupported("protocol", port.Protocol)) } allErrs = append(allErrs, pErrs.PrefixIndex(i)...) } return allErrs }
// ValidateService tests if required fields in the service are set. func ValidateService(service *api.Service, lister ServiceLister, ctx api.Context) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} if len(service.Name) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("name", service.Name)) } else if !util.IsDNS952Label(service.Name) { allErrs = append(allErrs, errs.NewFieldInvalid("name", service.Name, "")) } if !util.IsDNSSubdomain(service.Namespace) { allErrs = append(allErrs, errs.NewFieldInvalid("namespace", service.Namespace, "")) } if !util.IsValidPortNum(service.Spec.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("spec.port", service.Spec.Port, "")) } if len(service.Spec.Protocol) == 0 { service.Spec.Protocol = "TCP" } else if !supportedPortProtocols.Has(strings.ToUpper(string(service.Spec.Protocol))) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.protocol", service.Spec.Protocol)) } if service.Spec.Selector != nil { allErrs = append(allErrs, validateLabels(service.Spec.Selector, "spec.selector")...) } allErrs = append(allErrs, validateLabels(service.Labels, "labels")...) if service.Spec.CreateExternalLoadBalancer { services, err := lister.ListServices(ctx) if err != nil { allErrs = append(allErrs, errs.NewInternalError(err)) } else { for i := range services.Items { if services.Items[i].Name != service.Name && services.Items[i].Spec.CreateExternalLoadBalancer && services.Items[i].Spec.Port == service.Spec.Port { allErrs = append(allErrs, errs.NewConflict("service", service.Name, fmt.Errorf("port: %d is already in use", service.Spec.Port))) break } } } } if service.Spec.SessionAffinity == "" { service.Spec.SessionAffinity = api.AffinityTypeNone } else if !supportedSessionAffinityType.Has(string(service.Spec.SessionAffinity)) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.sessionAffinity", service.Spec.SessionAffinity)) } return allErrs }
func validateLabels(labels map[string]string) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} for k := range labels { if !util.IsDNS952Label(k) { allErrs = append(allErrs, errs.NewFieldNotSupported("label", k)) } } return allErrs }
func ValidatePodState(podState *api.PodState) errs.ErrorList { allErrs := errs.ErrorList(ValidateManifest(&podState.Manifest)).Prefix("manifest") if podState.RestartPolicy.Type == "" { podState.RestartPolicy.Type = api.RestartAlways } else if podState.RestartPolicy.Type != api.RestartAlways && podState.RestartPolicy.Type != api.RestartOnFailure && podState.RestartPolicy.Type != api.RestartNever { allErrs = append(allErrs, errs.NewFieldNotSupported("restartPolicy.type", podState.RestartPolicy.Type)) } return allErrs }
func validateDNSPolicy(dnsPolicy *api.DNSPolicy) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} switch *dnsPolicy { case api.DNSClusterFirst, api.DNSDefault: break case "": allErrors = append(allErrors, errs.NewFieldRequired("", *dnsPolicy)) default: allErrors = append(allErrors, errs.NewFieldNotSupported("", dnsPolicy)) } return allErrors }
func validateDNSPolicy(dnsPolicy *api.DNSPolicy) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} switch *dnsPolicy { case "": // TODO: move this out to standard defaulting logic, when that is ready. *dnsPolicy = api.DNSClusterFirst // Default value. case api.DNSClusterFirst, api.DNSDefault: break default: allErrors = append(allErrors, errs.NewFieldNotSupported("", dnsPolicy)) } return allErrors }
// ValidateManifest tests that the specified ContainerManifest has valid data. // This includes checking formatting and uniqueness. It also canonicalizes the // structure by setting default values and implementing any backwards-compatibility // tricks. func ValidateManifest(manifest *api.ContainerManifest) errs.ErrorList { allErrs := errs.ErrorList{} if len(manifest.Version) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("version", manifest.Version)) } else if !supportedManifestVersions.Has(strings.ToLower(manifest.Version)) { allErrs = append(allErrs, errs.NewFieldNotSupported("version", manifest.Version)) } allVolumes, errs := validateVolumes(manifest.Volumes) allErrs = append(allErrs, errs.Prefix("volumes")...) allErrs = append(allErrs, validateContainers(manifest.Containers, allVolumes).Prefix("containers")...) return allErrs }
func validateRestartPolicy(restartPolicy *api.RestartPolicy) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} switch *restartPolicy { case api.RestartPolicyAlways, api.RestartPolicyOnFailure, api.RestartPolicyNever: break case "": allErrors = append(allErrors, errs.NewFieldRequired("")) default: allErrors = append(allErrors, errs.NewFieldNotSupported("", restartPolicy)) } return allErrors }
func validatePullPolicy(ctr *api.Container) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} switch ctr.ImagePullPolicy { case api.PullAlways, api.PullIfNotPresent, api.PullNever: break case "": allErrors = append(allErrors, errs.NewFieldRequired("", ctr.ImagePullPolicy)) default: allErrors = append(allErrors, errs.NewFieldNotSupported("", ctr.ImagePullPolicy)) } return allErrors }
// ValidateService tests if required fields in the service are set. func ValidateService(service *api.Service) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName).Prefix("metadata")...) if !util.IsValidPortNum(service.Spec.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("spec.port", service.Spec.Port, portRangeErrorMsg)) } if len(service.Spec.Protocol) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("spec.protocol")) } else if !supportedPortProtocols.Has(strings.ToUpper(string(service.Spec.Protocol))) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.protocol", service.Spec.Protocol)) } if service.Spec.TargetPort.Kind == util.IntstrInt && service.Spec.TargetPort.IntVal != 0 && !util.IsValidPortNum(service.Spec.TargetPort.IntVal) { allErrs = append(allErrs, errs.NewFieldInvalid("spec.containerPort", service.Spec.Port, portRangeErrorMsg)) } else if service.Spec.TargetPort.Kind == util.IntstrString && len(service.Spec.TargetPort.StrVal) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("spec.containerPort")) } if service.Spec.Selector != nil { allErrs = append(allErrs, ValidateLabels(service.Spec.Selector, "spec.selector")...) } if service.Spec.SessionAffinity == "" { allErrs = append(allErrs, errs.NewFieldRequired("spec.sessionAffinity")) } else if !supportedSessionAffinityType.Has(string(service.Spec.SessionAffinity)) { allErrs = append(allErrs, errs.NewFieldNotSupported("spec.sessionAffinity", service.Spec.SessionAffinity)) } if api.IsServiceIPSet(service) { if ip := net.ParseIP(service.Spec.PortalIP); ip == nil { allErrs = append(allErrs, errs.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP, "portalIP should be empty, 'None', or a valid IP address")) } } return allErrs }
// ValidateService tests if required fields in the service are set. func ValidateService(service *api.Service) errs.ErrorList { allErrs := errs.ErrorList{} if len(service.ID) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("id", service.ID)) } else if !util.IsDNS952Label(service.ID) { allErrs = append(allErrs, errs.NewFieldInvalid("id", service.ID)) } if !util.IsValidPortNum(service.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("Service.Port", service.Port)) } if len(service.Protocol) == 0 { service.Protocol = "TCP" } else if !supportedPortProtocols.Has(strings.ToUpper(service.Protocol)) { allErrs = append(allErrs, errs.NewFieldNotSupported("protocol", service.Protocol)) } if labels.Set(service.Selector).AsSelector().Empty() { allErrs = append(allErrs, errs.NewFieldRequired("selector", service.Selector)) } return allErrs }
// TODO(dchen1107): Move this along with other defaulting values func validatePullPolicyWithDefault(ctr *api.Container) errs.ValidationErrorList { allErrors := errs.ValidationErrorList{} // TODO(dchen1107): Move ParseImageName code to pkg/util if len(ctr.ImagePullPolicy) == 0 { parts := strings.Split(ctr.Image, ":") // Check image tag if parts[len(parts)-1] == "latest" { ctr.ImagePullPolicy = api.PullAlways } else { ctr.ImagePullPolicy = api.PullIfNotPresent } } if ctr.ImagePullPolicy != api.PullAlways && ctr.ImagePullPolicy != api.PullIfNotPresent && ctr.ImagePullPolicy != api.PullNever { allErrors = append(allErrors, errs.NewFieldNotSupported("", ctr.ImagePullPolicy)) } return allErrors }
// TODO: unify with validation.validateLabels func validateLabelKey(k string) error { if !util.IsDNSLabel(k) { return errors.NewFieldNotSupported("key", k) } return nil }