package v1
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
"github.com/openshift/origin/pkg/api/extension"
internal "github.com/openshift/origin/pkg/cmd/server/api"
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
)
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 addConversionFuncs(scheme *runtime.Scheme) error {
return scheme.AddConversionFuncs(
convert_runtime_Object_To_runtime_RawExtension,
convert_runtime_RawExtension_To_runtime_Object,
func(in *NodeConfig, out *internal.NodeConfig, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *internal.NodeConfig, out *NodeConfig, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *KubernetesMasterConfig, out *internal.KubernetesMasterConfig, s conversion.Scope) error {
if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil {
return err
}
if out.DisabledAPIGroupVersions == nil {
out.DisabledAPIGroupVersions = map[string][]string{}
}
// the APILevels (whitelist) needs to be converted into an internal blacklist
if len(in.APILevels) == 0 {
out.DisabledAPIGroupVersions[internal.APIGroupKube] = []string{"*"}
} else {
availableLevels := internal.KubeAPIGroupsToAllowedVersions[internal.APIGroupKube]
whitelistedLevels := sets.NewString(in.APILevels...)
blacklistedLevels := []string{}
for _, curr := range availableLevels {
if !whitelistedLevels.Has(curr) {
blacklistedLevels = append(blacklistedLevels, curr)
}
}
if len(blacklistedLevels) > 0 {
out.DisabledAPIGroupVersions[internal.APIGroupKube] = blacklistedLevels
}
}
return nil
},
func(in *internal.KubernetesMasterConfig, out *KubernetesMasterConfig, s conversion.Scope) error {
// internal doesn't have all fields: APILevels
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
func(in *ServingInfo, out *internal.ServingInfo, s conversion.Scope) error {
if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil {
return err
}
out.ServerCert.CertFile = in.CertFile
out.ServerCert.KeyFile = in.KeyFile
return nil
},
func(in *internal.ServingInfo, out *ServingInfo, s conversion.Scope) error {
if err := s.DefaultConvert(in, out, conversion.IgnoreMissingFields); err != nil {
return err
}
out.CertFile = in.ServerCert.CertFile
out.KeyFile = in.ServerCert.KeyFile
return nil
},
func(in *RemoteConnectionInfo, out *internal.RemoteConnectionInfo, s conversion.Scope) error {
out.URL = in.URL
out.CA = in.CA
out.ClientCert.CertFile = in.CertFile
out.ClientCert.KeyFile = in.KeyFile
return nil
},
func(in *internal.RemoteConnectionInfo, out *RemoteConnectionInfo, s conversion.Scope) error {
out.URL = in.URL
out.CA = in.CA
out.CertFile = in.ClientCert.CertFile
out.KeyFile = in.ClientCert.KeyFile
return nil
},
func(in *EtcdConnectionInfo, out *internal.EtcdConnectionInfo, s conversion.Scope) error {
out.URLs = in.URLs
out.CA = in.CA
out.ClientCert.CertFile = in.CertFile
out.ClientCert.KeyFile = in.KeyFile
return nil
},
func(in *internal.EtcdConnectionInfo, out *EtcdConnectionInfo, s conversion.Scope) error {
out.URLs = in.URLs
out.CA = in.CA
out.CertFile = in.ClientCert.CertFile
out.KeyFile = in.ClientCert.KeyFile
return nil
},
func(in *KubeletConnectionInfo, out *internal.KubeletConnectionInfo, s conversion.Scope) error {
out.Port = in.Port
out.CA = in.CA
out.ClientCert.CertFile = in.CertFile
out.ClientCert.KeyFile = in.KeyFile
return nil
},
func(in *internal.KubeletConnectionInfo, out *KubeletConnectionInfo, s conversion.Scope) error {
out.Port = in.Port
out.CA = in.CA
out.CertFile = in.ClientCert.CertFile
out.KeyFile = in.ClientCert.KeyFile
return nil
},
func(in *MasterVolumeConfig, out *internal.MasterVolumeConfig, s conversion.Scope) error {
out.DynamicProvisioningEnabled = (in.DynamicProvisioningEnabled == nil) || (*in.DynamicProvisioningEnabled)
return nil
},
func(in *internal.MasterVolumeConfig, out *MasterVolumeConfig, s conversion.Scope) error {
enabled := in.DynamicProvisioningEnabled
out.DynamicProvisioningEnabled = &enabled
return nil
},
api.Convert_resource_Quantity_To_resource_Quantity,
api.Convert_bool_To_Pointer_bool,
api.Convert_Pointer_bool_To_bool,
)
}
// convert_runtime_Object_To_runtime_RawExtension attempts to convert runtime.Objects to the appropriate target.
func convert_runtime_Object_To_runtime_RawExtension(in *runtime.Object, out *runtime.RawExtension, s conversion.Scope) error {
return extension.Convert_runtime_Object_To_runtime_RawExtension(internal.Scheme, in, out, s)
}
// convert_runtime_RawExtension_To_runtime_Object attempts to convert an incoming object into the
// appropriate output type.
func convert_runtime_RawExtension_To_runtime_Object(in *runtime.RawExtension, out *runtime.Object, s conversion.Scope) error {
return extension.Convert_runtime_RawExtension_To_runtime_Object(internal.Scheme, in, out, s)
}
// setDefault_ClientConnectionOverrides defaults a client connection to the pre-1.3 settings of
// being JSON only. Callers must explicitly opt-in to Protobuf support in 1.3+.
func setDefault_ClientConnectionOverrides(overrides *ClientConnectionOverrides) {
if len(overrides.AcceptContentTypes) == 0 {
overrides.AcceptContentTypes = "application/json"
}
if len(overrides.ContentType) == 0 {
overrides.ContentType = "application/json"
}
}
var _ runtime.NestedObjectDecoder = &MasterConfig{}
// DecodeNestedObjects handles encoding RawExtensions on the MasterConfig, ensuring the
// objects are decoded with the provided decoder.
func (c *MasterConfig) DecodeNestedObjects(d runtime.Decoder) error {
// decoding failures result in a runtime.Unknown object being created in Object and passed
// to conversion
for k, v := range c.AdmissionConfig.PluginConfig {
extension.DecodeNestedRawExtensionOrUnknown(d, &v.Configuration)
c.AdmissionConfig.PluginConfig[k] = v
}
if c.KubernetesMasterConfig != nil {
for k, v := range c.KubernetesMasterConfig.AdmissionConfig.PluginConfig {
extension.DecodeNestedRawExtensionOrUnknown(d, &v.Configuration)
c.KubernetesMasterConfig.AdmissionConfig.PluginConfig[k] = v
}
}
if c.OAuthConfig != nil {
for i := range c.OAuthConfig.IdentityProviders {
extension.DecodeNestedRawExtensionOrUnknown(d, &c.OAuthConfig.IdentityProviders[i].Provider)
}
}
return nil
}
var _ runtime.NestedObjectEncoder = &MasterConfig{}
// EncodeNestedObjects handles encoding RawExtensions on the MasterConfig, ensuring the
// objects are encoded with the provided encoder.
func (c *MasterConfig) EncodeNestedObjects(e runtime.Encoder) error {
for k, v := range c.AdmissionConfig.PluginConfig {
if err := extension.EncodeNestedRawExtension(e, &v.Configuration); err != nil {
return err
}
c.AdmissionConfig.PluginConfig[k] = v
}
if c.KubernetesMasterConfig != nil {
for k, v := range c.KubernetesMasterConfig.AdmissionConfig.PluginConfig {
if err := extension.EncodeNestedRawExtension(e, &v.Configuration); err != nil {
return err
}
c.KubernetesMasterConfig.AdmissionConfig.PluginConfig[k] = v
}
}
if c.OAuthConfig != nil {
for i := range c.OAuthConfig.IdentityProviders {
if err := extension.EncodeNestedRawExtension(e, &c.OAuthConfig.IdentityProviders[i].Provider); err != nil {
return err
}
}
}
return nil
}