func ValidateIngressIPNetworkCIDR(config *api.MasterConfig, fldPath *field.Path) (errors field.ErrorList) { cidr := config.NetworkConfig.IngressIPNetworkCIDR if len(cidr) == 0 { return } addError := func(errMessage string) { errors = append(errors, field.Invalid(fldPath, cidr, errMessage)) } _, ipNet, err := net.ParseCIDR(cidr) if err != nil { addError("must be a valid CIDR notation IP range (e.g. 172.46.0.0/16)") return } // TODO Detect cloud provider when not using built-in kubernetes kubeConfig := config.KubernetesMasterConfig noCloudProvider := kubeConfig != nil && (len(kubeConfig.ControllerArguments["cloud-provider"]) == 0 || kubeConfig.ControllerArguments["cloud-provider"][0] == "") if noCloudProvider { if api.CIDRsOverlap(cidr, config.NetworkConfig.ClusterNetworkCIDR) { addError("conflicts with cluster network CIDR") } if api.CIDRsOverlap(cidr, config.NetworkConfig.ServiceNetworkCIDR) { addError("conflicts with service network CIDR") } } else if !ipNet.IP.IsUnspecified() { addError("should not be provided when a cloud-provider is enabled") } return }
func addDefaultingFuncs(scheme *runtime.Scheme) error { return scheme.AddDefaultingFuncs( func(obj *MasterConfig) { if len(obj.APILevels) == 0 { obj.APILevels = internal.DefaultOpenShiftAPILevels } if len(obj.Controllers) == 0 { obj.Controllers = ControllersAll } if obj.ServingInfo.RequestTimeoutSeconds == 0 { obj.ServingInfo.RequestTimeoutSeconds = 60 * 60 } if obj.ServingInfo.MaxRequestsInFlight == 0 { obj.ServingInfo.MaxRequestsInFlight = 500 } if len(obj.PolicyConfig.OpenShiftInfrastructureNamespace) == 0 { obj.PolicyConfig.OpenShiftInfrastructureNamespace = bootstrappolicy.DefaultOpenShiftInfraNamespace } if len(obj.RoutingConfig.Subdomain) == 0 { obj.RoutingConfig.Subdomain = "router.default.svc.cluster.local" } if len(obj.JenkinsPipelineConfig.TemplateNamespace) == 0 { obj.JenkinsPipelineConfig.TemplateNamespace = "openshift" } if len(obj.JenkinsPipelineConfig.TemplateName) == 0 { obj.JenkinsPipelineConfig.TemplateName = "jenkins-ephemeral" } if len(obj.JenkinsPipelineConfig.ServiceName) == 0 { obj.JenkinsPipelineConfig.ServiceName = "jenkins" } if obj.JenkinsPipelineConfig.AutoProvisionEnabled == nil { v := true obj.JenkinsPipelineConfig.AutoProvisionEnabled = &v } if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides == nil { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides = &ClientConnectionOverrides{} } // historical values if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.QPS <= 0 { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.QPS = 150.0 } if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.Burst <= 0 { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.Burst = 300 } setDefault_ClientConnectionOverrides(obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides) if obj.MasterClients.ExternalKubernetesClientConnectionOverrides == nil { obj.MasterClients.ExternalKubernetesClientConnectionOverrides = &ClientConnectionOverrides{} } // historical values if obj.MasterClients.ExternalKubernetesClientConnectionOverrides.QPS <= 0 { obj.MasterClients.ExternalKubernetesClientConnectionOverrides.QPS = 100.0 } if obj.MasterClients.ExternalKubernetesClientConnectionOverrides.Burst <= 0 { obj.MasterClients.ExternalKubernetesClientConnectionOverrides.Burst = 200 } setDefault_ClientConnectionOverrides(obj.MasterClients.ExternalKubernetesClientConnectionOverrides) // Populate the new NetworkConfig.ServiceNetworkCIDR field from the KubernetesMasterConfig.ServicesSubnet field if needed if len(obj.NetworkConfig.ServiceNetworkCIDR) == 0 { if obj.KubernetesMasterConfig != nil && len(obj.KubernetesMasterConfig.ServicesSubnet) > 0 { // if a subnet is set in the kubernetes master config, use that obj.NetworkConfig.ServiceNetworkCIDR = obj.KubernetesMasterConfig.ServicesSubnet } else { // default ServiceClusterIPRange used by kubernetes if nothing is specified obj.NetworkConfig.ServiceNetworkCIDR = "10.0.0.0/24" } } // TODO Detect cloud provider when not using built-in kubernetes kubeConfig := obj.KubernetesMasterConfig noCloudProvider := kubeConfig != nil && (len(kubeConfig.ControllerArguments["cloud-provider"]) == 0 || kubeConfig.ControllerArguments["cloud-provider"][0] == "") if noCloudProvider && len(obj.NetworkConfig.IngressIPNetworkCIDR) == 0 { cidr := internal.DefaultIngressIPNetworkCIDR if !(internal.CIDRsOverlap(cidr, obj.NetworkConfig.ClusterNetworkCIDR) || internal.CIDRsOverlap(cidr, obj.NetworkConfig.ServiceNetworkCIDR)) { obj.NetworkConfig.IngressIPNetworkCIDR = cidr } } // Historically, the clientCA was incorrectly used as the master's server cert CA bundle // If missing from the config, migrate the ClientCA into that field if obj.OAuthConfig != nil && obj.OAuthConfig.MasterCA == nil { s := obj.ServingInfo.ClientCA // The final value of OAuthConfig.MasterCA should never be nil obj.OAuthConfig.MasterCA = &s } }, func(obj *KubernetesMasterConfig) { if obj.MasterCount == 0 { obj.MasterCount = 1 } if len(obj.APILevels) == 0 { obj.APILevels = internal.DefaultKubernetesAPILevels } if len(obj.ServicesNodePortRange) == 0 { obj.ServicesNodePortRange = "30000-32767" } if len(obj.PodEvictionTimeout) == 0 { obj.PodEvictionTimeout = "5m" } }, func(obj *NodeConfig) { if obj.MasterClientConnectionOverrides == nil { obj.MasterClientConnectionOverrides = &ClientConnectionOverrides{ // historical values QPS: 10.0, Burst: 20, } } setDefault_ClientConnectionOverrides(obj.MasterClientConnectionOverrides) // Defaults/migrations for NetworkConfig if len(obj.NetworkConfig.NetworkPluginName) == 0 { obj.NetworkConfig.NetworkPluginName = obj.DeprecatedNetworkPluginName } if obj.NetworkConfig.MTU == 0 { obj.NetworkConfig.MTU = 1450 } if len(obj.IPTablesSyncPeriod) == 0 { obj.IPTablesSyncPeriod = "30s" } // Auth cache defaults if len(obj.AuthConfig.AuthenticationCacheTTL) == 0 { obj.AuthConfig.AuthenticationCacheTTL = "5m" } if obj.AuthConfig.AuthenticationCacheSize == 0 { obj.AuthConfig.AuthenticationCacheSize = 1000 } if len(obj.AuthConfig.AuthorizationCacheTTL) == 0 { obj.AuthConfig.AuthorizationCacheTTL = "5m" } if obj.AuthConfig.AuthorizationCacheSize == 0 { obj.AuthConfig.AuthorizationCacheSize = 1000 } // EnableUnidling by default if obj.EnableUnidling == nil { v := true obj.EnableUnidling = &v } }, func(obj *EtcdStorageConfig) { if len(obj.KubernetesStorageVersion) == 0 { obj.KubernetesStorageVersion = "v1" } if len(obj.KubernetesStoragePrefix) == 0 { obj.KubernetesStoragePrefix = "kubernetes.io" } if len(obj.OpenShiftStorageVersion) == 0 { obj.OpenShiftStorageVersion = internal.DefaultOpenShiftStorageVersionLevel } if len(obj.OpenShiftStoragePrefix) == 0 { obj.OpenShiftStoragePrefix = "openshift.io" } }, func(obj *DockerConfig) { if len(obj.ExecHandlerName) == 0 { obj.ExecHandlerName = DockerExecHandlerNative } }, func(obj *ServingInfo) { if len(obj.BindNetwork) == 0 { obj.BindNetwork = "tcp4" } }, func(obj *ImagePolicyConfig) { if obj.MaxImagesBulkImportedPerRepository == 0 { obj.MaxImagesBulkImportedPerRepository = 5 } if obj.MaxScheduledImageImportsPerMinute == 0 { obj.MaxScheduledImageImportsPerMinute = 60 } if obj.ScheduledImageImportMinimumIntervalSeconds == 0 { obj.ScheduledImageImportMinimumIntervalSeconds = 15 * 60 } }, func(obj *DNSConfig) { if len(obj.BindNetwork) == 0 { obj.BindNetwork = "tcp4" } }, func(obj *SecurityAllocator) { if len(obj.UIDAllocatorRange) == 0 { obj.UIDAllocatorRange = "1000000000-1999999999/10000" } if len(obj.MCSAllocatorRange) == 0 { obj.MCSAllocatorRange = "s0:/2" } if obj.MCSLabelsPerProject == 0 { obj.MCSLabelsPerProject = 5 } }, func(obj *IdentityProvider) { if len(obj.MappingMethod) == 0 { // By default, only let one identity provider authenticate a particular user // If multiple identity providers collide, the second one in will fail to auth // The admin can set this to "add" if they want to allow new identities to join existing users obj.MappingMethod = "claim" } }, func(obj *GrantConfig) { if len(obj.ServiceAccountMethod) == 0 { obj.ServiceAccountMethod = "prompt" } }, ) }
func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item runtime.Object, seed int64) runtime.Object { f := fuzzerFor(t, forVersion, rand.NewSource(seed)) f.Funcs( // these follow defaulting rules func(obj *configapi.MasterConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.APILevels) == 0 { obj.APILevels = configapi.DefaultOpenShiftAPILevels } if len(obj.Controllers) == 0 { obj.Controllers = configapi.ControllersAll } if obj.ServingInfo.RequestTimeoutSeconds == 0 { obj.ServingInfo.RequestTimeoutSeconds = 60 * 60 } if obj.ServingInfo.MaxRequestsInFlight == 0 { obj.ServingInfo.MaxRequestsInFlight = 500 } if len(obj.PolicyConfig.OpenShiftInfrastructureNamespace) == 0 { obj.PolicyConfig.OpenShiftInfrastructureNamespace = bootstrappolicy.DefaultOpenShiftInfraNamespace } if len(obj.RoutingConfig.Subdomain) == 0 { obj.RoutingConfig.Subdomain = "router.default.svc.cluster.local" } if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides == nil { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides = &configapi.ClientConnectionOverrides{ AcceptContentTypes: "test/second", ContentType: "test/first", } } if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.QPS <= 0 { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.QPS = 2.0 } if obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.Burst <= 0 { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.Burst = 2 } if len(obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.AcceptContentTypes) == 0 { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.AcceptContentTypes = "test/fourth" } if len(obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.ContentType) == 0 { obj.MasterClients.OpenShiftLoopbackClientConnectionOverrides.ContentType = "test/fifth" } if obj.MasterClients.ExternalKubernetesClientConnectionOverrides == nil { obj.MasterClients.ExternalKubernetesClientConnectionOverrides = &configapi.ClientConnectionOverrides{ AcceptContentTypes: "test/other", ContentType: "test/third", } } if obj.MasterClients.ExternalKubernetesClientConnectionOverrides.QPS <= 0 { obj.MasterClients.ExternalKubernetesClientConnectionOverrides.QPS = 2.0 } if obj.MasterClients.ExternalKubernetesClientConnectionOverrides.Burst <= 0 { obj.MasterClients.ExternalKubernetesClientConnectionOverrides.Burst = 2 } if len(obj.MasterClients.ExternalKubernetesClientConnectionOverrides.AcceptContentTypes) == 0 { obj.MasterClients.ExternalKubernetesClientConnectionOverrides.AcceptContentTypes = "test/fourth" } if len(obj.MasterClients.ExternalKubernetesClientConnectionOverrides.ContentType) == 0 { obj.MasterClients.ExternalKubernetesClientConnectionOverrides.ContentType = "test/fifth" } // Populate the new NetworkConfig.ServiceNetworkCIDR field from the KubernetesMasterConfig.ServicesSubnet field if needed if len(obj.NetworkConfig.ServiceNetworkCIDR) == 0 { if obj.KubernetesMasterConfig != nil && len(obj.KubernetesMasterConfig.ServicesSubnet) > 0 { // if a subnet is set in the kubernetes master config, use that obj.NetworkConfig.ServiceNetworkCIDR = obj.KubernetesMasterConfig.ServicesSubnet } else { // default ServiceClusterIPRange used by kubernetes if nothing is specified obj.NetworkConfig.ServiceNetworkCIDR = "10.0.0.0/24" } } // TODO stop duplicating the conversion in the test. kubeConfig := obj.KubernetesMasterConfig noCloudProvider := kubeConfig != nil && (len(kubeConfig.ControllerArguments["cloud-provider"]) == 0 || kubeConfig.ControllerArguments["cloud-provider"][0] == "") if noCloudProvider && len(obj.NetworkConfig.IngressIPNetworkCIDR) == 0 { cidr := "172.46.0.0/16" if !(configapi.CIDRsOverlap(cidr, obj.NetworkConfig.ClusterNetworkCIDR) || configapi.CIDRsOverlap(cidr, obj.NetworkConfig.ServiceNetworkCIDR)) { obj.NetworkConfig.IngressIPNetworkCIDR = cidr } } // Historically, the clientCA was incorrectly used as the master's server cert CA bundle // If missing from the config, migrate the ClientCA into that field if obj.OAuthConfig != nil && obj.OAuthConfig.MasterCA == nil { s := obj.ServingInfo.ClientCA // The final value of OAuthConfig.MasterCA should never be nil obj.OAuthConfig.MasterCA = &s } // test an admission plugin nested for round tripping if c.RandBool() { obj.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{ "abc": { Location: "test", Configuration: &configapi.LDAPSyncConfig{ URL: "ldap://*****:*****@server:8080/test", }, }, } } // test a Kubernetes admission plugin nested for round tripping if obj.KubernetesMasterConfig != nil && c.RandBool() { obj.KubernetesMasterConfig.AdmissionConfig.PluginConfig = map[string]configapi.AdmissionPluginConfig{ "abc": { Location: "test", Configuration: &configapi.LDAPSyncConfig{ URL: "ldap://*****:*****@server:8080/test", }, }, } } if obj.OAuthConfig != nil && c.RandBool() { obj.OAuthConfig.IdentityProviders = []configapi.IdentityProvider{ { MappingMethod: "claim", Provider: &configapi.LDAPSyncConfig{ URL: "ldap://*****:*****@server:8080/test", }, }, } } }, func(obj *configapi.KubernetesMasterConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if obj.MasterCount == 0 { obj.MasterCount = 1 } if len(obj.ServicesNodePortRange) == 0 { obj.ServicesNodePortRange = "30000-32767" } if len(obj.PodEvictionTimeout) == 0 { obj.PodEvictionTimeout = "5m" } }, func(obj *configapi.JenkinsPipelineConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if obj.AutoProvisionEnabled == nil { v := c.RandBool() obj.AutoProvisionEnabled = &v } if len(obj.TemplateNamespace) == 0 { obj.TemplateNamespace = "value" } if len(obj.TemplateName) == 0 { obj.TemplateName = "anothervalue" } if len(obj.ServiceName) == 0 { obj.ServiceName = "thirdvalue" } }, func(obj *configapi.NodeConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) // Defaults/migrations for NetworkConfig if len(obj.NetworkConfig.NetworkPluginName) == 0 { obj.NetworkConfig.NetworkPluginName = "plugin-name" } if obj.NetworkConfig.MTU == 0 { obj.NetworkConfig.MTU = 1450 } if len(obj.IPTablesSyncPeriod) == 0 { obj.IPTablesSyncPeriod = "5s" } if obj.MasterClientConnectionOverrides == nil { obj.MasterClientConnectionOverrides = &configapi.ClientConnectionOverrides{ QPS: 1.0, Burst: 1, AcceptContentTypes: "test/other", ContentType: "test/third", } } if len(obj.MasterClientConnectionOverrides.AcceptContentTypes) == 0 { obj.MasterClientConnectionOverrides.AcceptContentTypes = "test/fourth" } if len(obj.MasterClientConnectionOverrides.ContentType) == 0 { obj.MasterClientConnectionOverrides.ContentType = "test/fifth" } // Auth cache defaults if len(obj.AuthConfig.AuthenticationCacheTTL) == 0 { obj.AuthConfig.AuthenticationCacheTTL = "5m" } if obj.AuthConfig.AuthenticationCacheSize == 0 { obj.AuthConfig.AuthenticationCacheSize = 1000 } if len(obj.AuthConfig.AuthorizationCacheTTL) == 0 { obj.AuthConfig.AuthorizationCacheTTL = "5m" } if obj.AuthConfig.AuthorizationCacheSize == 0 { obj.AuthConfig.AuthorizationCacheSize = 1000 } }, func(obj *configapi.EtcdStorageConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.KubernetesStorageVersion) == 0 { obj.KubernetesStorageVersion = "v1" } if len(obj.KubernetesStoragePrefix) == 0 { obj.KubernetesStoragePrefix = "kubernetes.io" } if len(obj.OpenShiftStorageVersion) == 0 { obj.OpenShiftStorageVersion = configapi.DefaultOpenShiftStorageVersionLevel } if len(obj.OpenShiftStoragePrefix) == 0 { obj.OpenShiftStoragePrefix = "openshift.io" } }, func(obj *configapi.DockerConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.ExecHandlerName) == 0 { obj.ExecHandlerName = configapi.DockerExecHandlerNative } }, func(obj *configapi.ServingInfo, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.BindNetwork) == 0 { obj.BindNetwork = "tcp4" } }, func(obj *configapi.ImagePolicyConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if obj.MaxImagesBulkImportedPerRepository == 0 { obj.MaxImagesBulkImportedPerRepository = 5 } if obj.MaxScheduledImageImportsPerMinute == 0 { obj.MaxScheduledImageImportsPerMinute = 60 } if obj.ScheduledImageImportMinimumIntervalSeconds == 0 { obj.ScheduledImageImportMinimumIntervalSeconds = 15 * 60 } }, func(obj *configapi.DNSConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.BindNetwork) == 0 { obj.BindNetwork = "tcp4" } }, func(obj *configapi.SecurityAllocator, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.UIDAllocatorRange) == 0 { obj.UIDAllocatorRange = "1000000000-1999999999/10000" } if len(obj.MCSAllocatorRange) == 0 { obj.MCSAllocatorRange = "s0:/2" } if obj.MCSLabelsPerProject == 0 { obj.MCSLabelsPerProject = 5 } }, func(obj *configapi.IdentityProvider, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.MappingMethod) == 0 { // By default, only let one identity provider authenticate a particular user // If multiple identity providers collide, the second one in will fail to auth // The admin can set this to "add" if they want to allow new identities to join existing users obj.MappingMethod = "claim" } }, func(s *configapi.StringSource, c fuzz.Continue) { if c.RandBool() { c.Fuzz(&s.Value) } else { c.Fuzz(&s.StringSourceSpec) } }, func(obj *podnodeapi.PodNodeConstraintsConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if obj.NodeSelectorLabelBlacklist == nil { obj.NodeSelectorLabelBlacklist = []string{"kubernetes.io/hostname"} } }, func(obj *labels.Selector, c fuzz.Continue) { }, func(obj *imagepolicyapi.ImagePolicyConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) for i := range obj.ExecutionRules { if len(obj.ExecutionRules[i].OnResources) == 0 { obj.ExecutionRules[i].OnResources = []unversioned.GroupResource{{Resource: "pods"}} } obj.ExecutionRules[i].MatchImageLabelSelectors = nil } if len(obj.ResolveImages) == 0 { obj.ResolveImages = imagepolicyapi.Attempt } }, func(obj *configapi.GrantConfig, c fuzz.Continue) { c.FuzzNoCustom(obj) if len(obj.ServiceAccountMethod) == 0 { obj.ServiceAccountMethod = "prompt" } }, ) f.Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, item) } j.SetKind("") j.SetAPIVersion("") return item }