diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index 00fdc75b749..d1e40d8b19f 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -63,11 +63,25 @@ type ClusterConfiguration struct { API API // Etcd holds configuration for etcd. Etcd Etcd + // Networking holds configuration for the networking topology of the cluster. Networking Networking // KubernetesVersion is the target version of the control plane. KubernetesVersion string + // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it + // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. + // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort + // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, + // the BindPort is used. + // Possible usages are: + // e.g. In an cluster with more than one control plane instances, this field should be + // assigned the address of the external load balancer in front of the + // control plane instances. + // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint + // could be used for assigning a stable DNS to the control plane. + ControlPlaneEndpoint string + // APIServerExtraArgs is a set of extra flags to pass to the API Server or override // default ones in form of =. // TODO: This is temporary and ideally we would like to switch all components to @@ -138,18 +152,7 @@ func (cc ComponentConfigs) Fuzz(c fuzz.Continue) {} type API struct { // AdvertiseAddress sets the IP address for the API server to advertise. AdvertiseAddress string - // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it - // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. - // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort - // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, - // the BindPort is used. - // Possible usages are: - // e.g. In an cluster with more than one control plane instances, this field should be - // assigned the address of the external load balancer in front of the - // control plane instances. - // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint - // could be used for assigning a stable DNS to the control plane. - ControlPlaneEndpoint string + // BindPort sets the secure port for the API Server to bind to. // Defaults to 6443. BindPort int32 diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go index ade16575723..91cb75b991f 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go @@ -32,51 +32,72 @@ func Convert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitCon if err := autoConvert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s); err != nil { return err } + if err := split_v1alpha2_InitConfiguration_into_kubeadm_ClusterConfiguration(in, &out.ClusterConfiguration, s); err != nil { + return err + } + return nil +} +func split_v1alpha2_InitConfiguration_into_kubeadm_ClusterConfiguration(in *InitConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error { + if err := split_v1alpha2_InitConfiguration_into_kubeadm_ComponentConfigs(in, &out.ComponentConfigs, s); err != nil { + return err + } + if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.API, s); err != nil { + return err + } + if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil { + return err + } + if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + return err + } + out.KubernetesVersion = in.KubernetesVersion + out.ControlPlaneEndpoint = in.API.ControlPlaneEndpoint + out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) + out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) + out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) + out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) + out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) + out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) + out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + out.CertificatesDir = in.CertificatesDir + out.ImageRepository = in.ImageRepository + out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterName = in.ClusterName + return nil +} + +func Convert_v1alpha2_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion.Scope) error { + if err := autoConvert_v1alpha2_API_To_kubeadm_API(in, out, s); err != nil { + return err + } + // in.ControlPlaneEndpoint is assigned outside this function + return nil +} + +func split_v1alpha2_InitConfiguration_into_kubeadm_ComponentConfigs(in *InitConfiguration, out *kubeadm.ComponentConfigs, s conversion.Scope) error { if in.KubeProxy.Config != nil { - if out.ComponentConfigs.KubeProxy == nil { - out.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{} + if out.KubeProxy == nil { + out.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{} } - if err := componentconfigs.Scheme.Convert(in.KubeProxy.Config, out.ComponentConfigs.KubeProxy, nil); err != nil { + if err := componentconfigs.Scheme.Convert(in.KubeProxy.Config, out.KubeProxy, nil); err != nil { return err } } if in.KubeletConfiguration.BaseConfig != nil { - if out.ComponentConfigs.Kubelet == nil { - out.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{} + if out.Kubelet == nil { + out.Kubelet = &kubeletconfig.KubeletConfiguration{} } - if err := componentconfigs.Scheme.Convert(in.KubeletConfiguration.BaseConfig, out.ComponentConfigs.Kubelet, nil); err != nil { + if err := componentconfigs.Scheme.Convert(in.KubeletConfiguration.BaseConfig, out.Kubelet, nil); err != nil { return err } } - - if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.ClusterConfiguration.API, s); err != nil { - return err - } - if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.ClusterConfiguration.Etcd, s); err != nil { - return err - } - if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.ClusterConfiguration.Networking, s); err != nil { - return err - } - out.ClusterConfiguration.KubernetesVersion = in.KubernetesVersion - out.ClusterConfiguration.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ClusterConfiguration.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.ClusterConfiguration.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.ClusterConfiguration.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ClusterConfiguration.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.ClusterConfiguration.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.ClusterConfiguration.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) - out.ClusterConfiguration.CertificatesDir = in.CertificatesDir - out.ClusterConfiguration.ImageRepository = in.ImageRepository - out.ClusterConfiguration.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage - if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.ClusterConfiguration.AuditPolicyConfiguration, s); err != nil { - return err - } - out.ClusterConfiguration.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) - out.ClusterConfiguration.ClusterName = in.ClusterName return nil } @@ -84,51 +105,71 @@ func Convert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kubeadm if err := autoConvert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in, out, s); err != nil { return err } + if err := join_kubeadm_ClusterConfiguration_into_v1alpha2_InitConfiguration(&in.ClusterConfiguration, out, s); err != nil { + return err + } + return nil +} - if in.ComponentConfigs.KubeProxy != nil { +func join_kubeadm_ClusterConfiguration_into_v1alpha2_InitConfiguration(in *kubeadm.ClusterConfiguration, out *InitConfiguration, s conversion.Scope) error { + if err := join_kubeadm_ComponentConfigs_into_v1alpha2_InitConfiguration(&in.ComponentConfigs, out, s); err != nil { + return err + } + if err := Convert_kubeadm_API_To_v1alpha2_API(&in.API, &out.API, s); err != nil { + return err + } + if err := Convert_kubeadm_Etcd_To_v1alpha2_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_kubeadm_Networking_To_v1alpha2_Networking(&in.Networking, &out.Networking, s); err != nil { + return err + } + if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha2_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + return err + } + out.KubernetesVersion = in.KubernetesVersion + out.API.ControlPlaneEndpoint = in.ControlPlaneEndpoint + out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) + out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) + out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) + out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) + out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) + out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) + out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + out.CertificatesDir = in.CertificatesDir + out.ImageRepository = in.ImageRepository + out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterName = in.ClusterName + return nil +} + +func Convert_kubeadm_API_To_v1alpha2_API(in *kubeadm.API, out *API, s conversion.Scope) error { + if err := autoConvert_kubeadm_API_To_v1alpha2_API(in, out, s); err != nil { + return err + } + // out.ControlPlaneEndpoint is assigned outside this function + return nil +} + +func join_kubeadm_ComponentConfigs_into_v1alpha2_InitConfiguration(in *kubeadm.ComponentConfigs, out *InitConfiguration, s conversion.Scope) error { + if in.KubeProxy != nil { if out.KubeProxy.Config == nil { out.KubeProxy.Config = &kubeproxyconfigv1alpha1.KubeProxyConfiguration{} } - if err := componentconfigs.Scheme.Convert(in.ComponentConfigs.KubeProxy, out.KubeProxy.Config, nil); err != nil { + if err := componentconfigs.Scheme.Convert(in.KubeProxy, out.KubeProxy.Config, nil); err != nil { return err } } - if in.ComponentConfigs.Kubelet != nil { + if in.Kubelet != nil { if out.KubeletConfiguration.BaseConfig == nil { out.KubeletConfiguration.BaseConfig = &kubeletconfigv1beta1.KubeletConfiguration{} } - if err := componentconfigs.Scheme.Convert(in.ComponentConfigs.Kubelet, out.KubeletConfiguration.BaseConfig, nil); err != nil { + if err := componentconfigs.Scheme.Convert(in.Kubelet, out.KubeletConfiguration.BaseConfig, nil); err != nil { return err } } - - if err := Convert_kubeadm_API_To_v1alpha2_API(&in.ClusterConfiguration.API, &out.API, s); err != nil { - return err - } - if err := Convert_kubeadm_Etcd_To_v1alpha2_Etcd(&in.ClusterConfiguration.Etcd, &out.Etcd, s); err != nil { - return err - } - if err := Convert_kubeadm_Networking_To_v1alpha2_Networking(&in.ClusterConfiguration.Networking, &out.Networking, s); err != nil { - return err - } - out.KubernetesVersion = in.ClusterConfiguration.KubernetesVersion - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ClusterConfiguration.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ClusterConfiguration.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ClusterConfiguration.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ClusterConfiguration.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ClusterConfiguration.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ClusterConfiguration.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ClusterConfiguration.APIServerCertSANs)) - out.CertificatesDir = in.ClusterConfiguration.CertificatesDir - out.ImageRepository = in.ClusterConfiguration.ImageRepository - out.UnifiedControlPlaneImage = in.ClusterConfiguration.UnifiedControlPlaneImage - if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha2_AuditPolicyConfiguration(&in.ClusterConfiguration.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { - return err - } - out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.ClusterConfiguration.FeatureGates)) - out.ClusterName = in.ClusterConfiguration.ClusterName - return nil } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go index f374a21feb5..3dcce0fc7bb 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go @@ -157,11 +157,21 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*kubeadm.API)(nil), (*API)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_API_To_v1alpha2_API(a.(*kubeadm.API), b.(*API), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*kubeadm.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope) }); err != nil { return err } + if err := s.AddConversionFunc((*API)(nil), (*kubeadm.API)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_API_To_kubeadm_API(a.(*API), b.(*kubeadm.API), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope) }); err != nil { @@ -172,28 +182,17 @@ func RegisterConversions(s *runtime.Scheme) error { func autoConvert_v1alpha2_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion.Scope) error { out.AdvertiseAddress = in.AdvertiseAddress - out.ControlPlaneEndpoint = in.ControlPlaneEndpoint + // WARNING: in.ControlPlaneEndpoint requires manual conversion: does not exist in peer-type out.BindPort = in.BindPort return nil } -// Convert_v1alpha2_API_To_kubeadm_API is an autogenerated conversion function. -func Convert_v1alpha2_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion.Scope) error { - return autoConvert_v1alpha2_API_To_kubeadm_API(in, out, s) -} - func autoConvert_kubeadm_API_To_v1alpha2_API(in *kubeadm.API, out *API, s conversion.Scope) error { out.AdvertiseAddress = in.AdvertiseAddress - out.ControlPlaneEndpoint = in.ControlPlaneEndpoint out.BindPort = in.BindPort return nil } -// Convert_kubeadm_API_To_v1alpha2_API is an autogenerated conversion function. -func Convert_kubeadm_API_To_v1alpha2_API(in *kubeadm.API, out *API, s conversion.Scope) error { - return autoConvert_kubeadm_API_To_v1alpha2_API(in, out, s) -} - func autoConvert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(in *AuditPolicyConfiguration, out *kubeadm.AuditPolicyConfiguration, s conversion.Scope) error { out.Path = in.Path out.LogDir = in.LogDir diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go index 82242126a69..b8508710b81 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go @@ -56,12 +56,26 @@ type ClusterConfiguration struct { API API `json:"api"` // Etcd holds configuration for etcd. Etcd Etcd `json:"etcd"` + // Networking holds configuration for the networking topology of the cluster. Networking Networking `json:"networking"` // KubernetesVersion is the target version of the control plane. KubernetesVersion string `json:"kubernetesVersion"` + // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it + // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. + // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort + // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, + // the BindPort is used. + // Possible usages are: + // e.g. In an cluster with more than one control plane instances, this field should be + // assigned the address of the external load balancer in front of the + // control plane instances. + // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint + // could be used for assigning a stable DNS to the control plane. + ControlPlaneEndpoint string `json:"controlPlaneEndpoint"` + // APIServerExtraArgs is a set of extra flags to pass to the API Server or override // default ones in form of =. // TODO: This is temporary and ideally we would like to switch all components to @@ -111,18 +125,7 @@ type ClusterConfiguration struct { type API struct { // AdvertiseAddress sets the IP address for the API server to advertise. AdvertiseAddress string `json:"advertiseAddress"` - // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it - // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. - // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort - // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, - // the BindPort is used. - // Possible usages are: - // e.g. In an cluster with more than one control plane instances, this field should be - // assigned the address of the external load balancer in front of the - // control plane instances. - // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint - // could be used for assigning a stable DNS to the control plane. - ControlPlaneEndpoint string `json:"controlPlaneEndpoint"` + // BindPort sets the secure port for the API Server to bind to. // Defaults to 6443. BindPort int32 `json:"bindPort"` diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go index a5ca999b137..28307b321b9 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go @@ -177,7 +177,6 @@ func RegisterConversions(s *runtime.Scheme) error { func autoConvert_v1alpha3_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion.Scope) error { out.AdvertiseAddress = in.AdvertiseAddress - out.ControlPlaneEndpoint = in.ControlPlaneEndpoint out.BindPort = in.BindPort return nil } @@ -189,7 +188,6 @@ func Convert_v1alpha3_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion func autoConvert_kubeadm_API_To_v1alpha3_API(in *kubeadm.API, out *API, s conversion.Scope) error { out.AdvertiseAddress = in.AdvertiseAddress - out.ControlPlaneEndpoint = in.ControlPlaneEndpoint out.BindPort = in.BindPort return nil } @@ -286,6 +284,7 @@ func autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(i return err } out.KubernetesVersion = in.KubernetesVersion + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) @@ -316,6 +315,7 @@ func autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(i return err } out.KubernetesVersion = in.KubernetesVersion + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go index c2933ff1fb0..dfd5acbbd13 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go @@ -22,6 +22,7 @@ import ( "net/url" "os" "path/filepath" + "strconv" "strings" "github.com/spf13/pflag" @@ -57,7 +58,8 @@ func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorLi allErrs = append(allErrs, ValidateCertSANs(c.APIServerCertSANs, field.NewPath("apiServerCertSANs"))...) allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificatesDir"))...) allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...) - allErrs = append(allErrs, ValidateAPIEndpoint(&c.API, field.NewPath("api"))...) + allErrs = append(allErrs, ValidateAPI(&c.API, field.NewPath("api"))...) + allErrs = append(allErrs, ValidateHostPort(c.ControlPlaneEndpoint, field.NewPath("controlPlaneEndpoint"))...) allErrs = append(allErrs, ValidateEtcd(&c.Etcd, field.NewPath("etcd"))...) allErrs = append(allErrs, componentconfigs.Known.Validate(c)...) return allErrs @@ -312,6 +314,24 @@ func ValidateIPFromString(ipaddr string, fldPath *field.Path) field.ErrorList { return allErrs } +// ValidatePort validates port numbers +func ValidatePort(port int32, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if _, err := kubeadmutil.ParsePort(strconv.Itoa(int(port))); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, port, "port number is not valid")) + } + return allErrs +} + +// ValidateHostPort validates host[:port] endpoints +func ValidateHostPort(endpoint string, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + if _, _, err := kubeadmutil.ParseHostPort(endpoint); endpoint != "" && err != nil { + allErrs = append(allErrs, field.Invalid(fldPath, endpoint, "endpoint is not valid")) + } + return allErrs +} + // ValidateIPNetFromString validates network portion of ip address func ValidateIPNetFromString(subnet string, minAddrs int64, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} @@ -385,14 +405,11 @@ func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) fie return allErrs } -// ValidateAPIEndpoint validates API server's endpoint -func ValidateAPIEndpoint(c *kubeadm.API, fldPath *field.Path) field.ErrorList { +// ValidateAPI validates API configuration +func ValidateAPI(c *kubeadm.API, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - - endpoint, err := kubeadmutil.GetMasterEndpoint(c) - if err != nil { - allErrs = append(allErrs, field.Invalid(fldPath, endpoint, err.Error())) - } + allErrs = append(allErrs, ValidateIPFromString(c.AdvertiseAddress, fldPath.Child("advertiseAddress"))...) + allErrs = append(allErrs, ValidatePort(c.BindPort, fldPath.Child("bindPort"))...) return allErrs } diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go index aef7ec03ba0..4d16d182bcf 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go @@ -218,202 +218,65 @@ func TestValidateIPNetFromString(t *testing.T) { } } -func TestValidateAPIEndpoint(t *testing.T) { +func TestValidateHostPort(t *testing.T) { var tests = []struct { name string - s *kubeadm.InitConfiguration + s string expected bool }{ { - name: "Missing configuration", - s: &kubeadm.InitConfiguration{}, + name: "Valid DNS address / port", + s: "cp.k8s.io:8081", + expected: true, + }, + { + name: "Valid DNS address", + s: "cp.k8s.io", + expected: true, + }, + { + name: "Valid IPv4 address / port", + s: "1.2.3.4:8081", + expected: true, + }, + { + name: "Valid IPv4 address", + s: "1.2.3.4", + expected: true, + }, + { + name: "Valid IPv6 address / port", + s: "[2001:db7::1]:8081", + expected: true, + }, + { + name: "Valid IPv6 address", + s: "2001:db7::1", + expected: true, + }, + { + name: "Invalid IPv4 address, but valid DNS", + s: "1.2.34", + expected: true, + }, + { + name: "Invalid DNS", + s: "a.B.c.d.e", expected: false, }, { - name: "Valid DNS ControlPlaneEndpoint (with port), AdvertiseAddress and default port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "cp.k8s.io:8081", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid IPv4 ControlPlaneEndpoint (with port), AdvertiseAddress and default port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1.2.3.4:8081", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid IPv6 ControlPlaneEndpoint (with port), ControlPlaneEndpoint and port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "[2001:db7::1]:8081", - AdvertiseAddress: "2001:db7::2", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid DNS ControlPlaneEndpoint (without port), AdvertiseAddress and default port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "cp.k8s.io", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid IPv4 ControlPlaneEndpoint (without port), AdvertiseAddress and default port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1.2.3.4", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid IPv6 ControlPlaneEndpoint (without port), ControlPlaneEndpoint and port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "2001:db7::1", - AdvertiseAddress: "2001:db7::2", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid IPv4 AdvertiseAddress and default port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - }, - }, - expected: true, - }, - { - name: "Valid IPv6 AdvertiseAddress and port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "2001:db7::1", - BindPort: 3446, - }, - }, - }, - expected: true, - }, - { - name: "Invalid IPv4 AdvertiseAddress", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.34", - BindPort: 6443, - }, - }, - }, + name: "Invalid IPv6 address", + s: "2001:db7:1", expected: false, }, { - name: "Invalid IPv6 AdvertiseAddress", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "2001:db7:1", - BindPort: 3446, - }, - }, - }, - expected: false, - }, - { - name: "Invalid BindPort", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 0, - }, - }, - }, - expected: false, - }, - { - name: "Invalid DNS ControlPlaneEndpoint", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "bad!!.k8s.io", - }, - }, - }, - expected: false, - }, - { - name: "Invalid ipv4 ControlPlaneEndpoint", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1..3.4", - }, - }, - }, - expected: false, - }, - { - name: "Invalid ipv6 ControlPlaneEndpoint", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313", - }, - }, - }, - expected: false, - }, - { - name: "Invalid ControlPlaneEndpoint port", - s: &kubeadm.InitConfiguration{ - ClusterConfiguration: kubeadm.ClusterConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1.2.3.4:0", - }, - }, - }, + name: "Invalid BindPort", + s: "1.2.3.4:0", expected: false, }, } for _, rt := range tests { - actual := ValidateAPIEndpoint(&rt.s.API, nil) + actual := ValidateHostPort(rt.s, nil) if (len(actual) == 0) != rt.expected { t.Errorf( "%s test case failed:\n\texpected: %t\n\t actual: %t", @@ -425,6 +288,67 @@ func TestValidateAPIEndpoint(t *testing.T) { } } +func TestValidateAPI(t *testing.T) { + var tests = []struct { + name string + s *kubeadm.API + expected bool + }{ + { + name: "Valid IPv4 address / port", + s: &kubeadm.API{ + AdvertiseAddress: "4.5.6.7", + BindPort: 6443, + }, + expected: true, + }, + { + name: "Valid IPv6 address / port", + s: &kubeadm.API{ + AdvertiseAddress: "2001:db7::2", + BindPort: 6443, + }, + expected: true, + }, + { + name: "Invalid IPv4 address", + s: &kubeadm.API{ + AdvertiseAddress: "1.2.34", + BindPort: 6443, + }, + expected: false, + }, + { + name: "Invalid IPv6 address", + s: &kubeadm.API{ + AdvertiseAddress: "2001:db7:1", + BindPort: 6443, + }, + expected: false, + }, + { + name: "Invalid BindPort", + s: &kubeadm.API{ + AdvertiseAddress: "4.5.6.7", + BindPort: 0, + }, + expected: false, + }, + } + for _, rt := range tests { + actual := ValidateAPI(rt.s, nil) + if (len(actual) == 0) != rt.expected { + t.Errorf( + "%s test case failed:\n\texpected: %t\n\t actual: %t", + rt.name, + rt.expected, + (len(actual) == 0), + ) + } + } +} + +//TODO: Create a separated test for ValidateClusterConfiguration func TestValidateInitConfiguration(t *testing.T) { nodename := "valid-nodename" var tests = []struct { diff --git a/cmd/kubeadm/app/cmd/join.go b/cmd/kubeadm/app/cmd/join.go index f879f731ef6..eccdebda1ad 100644 --- a/cmd/kubeadm/app/cmd/join.go +++ b/cmd/kubeadm/app/cmd/join.go @@ -72,7 +72,7 @@ var ( {{.Error}} Please ensure that: - * The cluster has a stable api.controlPlaneEndpoint address. + * The cluster has a stable controlPlaneEndpoint address. * The cluster uses an external etcd. * The certificates that must be shared among control plane instances are provided. @@ -388,8 +388,8 @@ func (j *Join) FetchInitClusterConfiguration(tlsBootstrapCfg *clientcmdapi.Confi // joining an additional control plane instance and if the node is ready to join func (j *Join) CheckIfReadyForAdditionalControlPlane(clusterConfiguration *kubeadmapi.InitConfiguration) error { // blocks if the cluster was created without a stable control plane endpoint - if clusterConfiguration.API.ControlPlaneEndpoint == "" { - return fmt.Errorf("unable to add a new control plane instance a cluster that doesn't have a stable api.controlPlaneEndpoint address") + if clusterConfiguration.ControlPlaneEndpoint == "" { + return fmt.Errorf("unable to add a new control plane instance a cluster that doesn't have a stable controlPlaneEndpoint address") } // blocks if the cluster was created without an external etcd cluster diff --git a/cmd/kubeadm/app/cmd/upgrade/common_test.go b/cmd/kubeadm/app/cmd/upgrade/common_test.go index fde2b8a82b8..4407182879a 100644 --- a/cmd/kubeadm/app/cmd/upgrade/common_test.go +++ b/cmd/kubeadm/app/cmd/upgrade/common_test.go @@ -46,12 +46,12 @@ func TestPrintConfiguration(t *testing.T) { api: advertiseAddress: "" bindPort: 0 - controlPlaneEndpoint: "" apiVersion: kubeadm.k8s.io/v1alpha3 auditPolicy: logDir: "" path: "" certificatesDir: "" + controlPlaneEndpoint: "" etcd: local: dataDir: /some/path @@ -82,12 +82,12 @@ func TestPrintConfiguration(t *testing.T) { api: advertiseAddress: "" bindPort: 0 - controlPlaneEndpoint: "" apiVersion: kubeadm.k8s.io/v1alpha3 auditPolicy: logDir: "" path: "" certificatesDir: "" + controlPlaneEndpoint: "" etcd: external: caFile: "" diff --git a/cmd/kubeadm/app/phases/addons/proxy/proxy.go b/cmd/kubeadm/app/phases/addons/proxy/proxy.go index e11763a124a..22a7479dd2e 100644 --- a/cmd/kubeadm/app/phases/addons/proxy/proxy.go +++ b/cmd/kubeadm/app/phases/addons/proxy/proxy.go @@ -52,7 +52,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf } // Generate Master Enpoint kubeconfig file - masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API) + masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) if err != nil { return err } diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go index e9d9f301b80..aa0a7a6988e 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go +++ b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers.go @@ -284,16 +284,16 @@ func GetAPIServerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames }, } - // add api server controlPlaneEndpoint if present (dns or ip) - if len(cfg.API.ControlPlaneEndpoint) > 0 { - if host, _, err := kubeadmutil.ParseHostPort(cfg.API.ControlPlaneEndpoint); err == nil { + // add cluster controlPlaneEndpoint if present (dns or ip) + if len(cfg.ControlPlaneEndpoint) > 0 { + if host, _, err := kubeadmutil.ParseHostPort(cfg.ControlPlaneEndpoint); err == nil { if ip := net.ParseIP(host); ip != nil { altNames.IPs = append(altNames.IPs, ip) } else { altNames.DNSNames = append(altNames.DNSNames, host) } } else { - return nil, fmt.Errorf("error parsing API api.controlPlaneEndpoint %q: %s", cfg.API.ControlPlaneEndpoint, err) + return nil, fmt.Errorf("error parsing cluster controlPlaneEndpoint %q: %s", cfg.ControlPlaneEndpoint, err) } } diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go index 86b00146e51..5598dd4347f 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go +++ b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go @@ -447,9 +447,10 @@ func TestGetAPIServerAltNames(t *testing.T) { name: "ControlPlaneEndpoint DNS", cfg: &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:6443"}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, + ControlPlaneEndpoint: "api.k8s.io:6443", + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, @@ -460,9 +461,10 @@ func TestGetAPIServerAltNames(t *testing.T) { name: "ControlPlaneEndpoint IP", cfg: &kubeadmapi.InitConfiguration{ ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "4.5.6.7:6443"}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, + ControlPlaneEndpoint: "4.5.6.7:6443", + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go index f994859b407..c7a09a50457 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go @@ -156,7 +156,7 @@ func getKubeConfigSpecs(cfg *kubeadmapi.InitConfiguration) (map[string]*kubeConf return nil, fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err) } - masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API) + masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) if err != nil { return nil, err } @@ -293,7 +293,7 @@ func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfigurat return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err) } - masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API) + masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) if err != nil { return err } @@ -320,7 +320,7 @@ func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration, return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err) } - masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API) + masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) if err != nil { return err } diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go index 3817e2f890e..5c16d233e91 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go @@ -74,29 +74,33 @@ func TestGetKubeConfigSpecs(t *testing.T) { }, { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234}, - CertificatesDir: pkidir, + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + ControlPlaneEndpoint: "api.k8s.io", + CertificatesDir: pkidir, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234}, - CertificatesDir: pkidir, + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + ControlPlaneEndpoint: "api.k8s.io:4321", + CertificatesDir: pkidir, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234}, - CertificatesDir: pkidir, + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + ControlPlaneEndpoint: "api.k8s.io", + CertificatesDir: pkidir, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { ClusterConfiguration: kubeadmapi.ClusterConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234}, - CertificatesDir: pkidir, + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + ControlPlaneEndpoint: "api.k8s.io:4321", + CertificatesDir: pkidir, }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, @@ -155,7 +159,7 @@ func TestGetKubeConfigSpecs(t *testing.T) { } // Asserts InitConfiguration values injected into spec - masterEndpoint, err := kubeadmutil.GetMasterEndpoint(&cfg.API) + masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg) if err != nil { t.Error(err) } diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml index a2d266011e0..96988081553 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/internal.yaml @@ -1,7 +1,6 @@ API: AdvertiseAddress: 192.168.2.2 BindPort: 6443 - ControlPlaneEndpoint: "" APIServerCertSANs: null APIServerExtraArgs: authorization-mode: Node,RBAC,Webhook @@ -157,6 +156,7 @@ ComponentConfigs: TLSMinVersion: "" TLSPrivateKeyFile: "" VolumeStatsAggPeriod: 1m0s +ControlPlaneEndpoint: "" ControllerManagerExtraArgs: null ControllerManagerExtraVolumes: null Etcd: diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml index c1f9d77e8f1..1cc2af59ab4 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml @@ -18,7 +18,6 @@ nodeRegistration: api: advertiseAddress: 192.168.2.2 bindPort: 6443 - controlPlaneEndpoint: "" apiServerExtraArgs: authorization-mode: Node,RBAC,Webhook apiVersion: kubeadm.k8s.io/v1alpha3 @@ -28,6 +27,7 @@ auditPolicy: path: "" certificatesDir: /etc/kubernetes/pki clusterName: kubernetes +controlPlaneEndpoint: "" etcd: local: dataDir: /var/lib/etcd diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml index 4eb86dd7d78..4d6f3173c64 100644 --- a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml @@ -18,7 +18,6 @@ nodeRegistration: api: advertiseAddress: 192.168.2.2 bindPort: 6443 - controlPlaneEndpoint: "" apiVersion: kubeadm.k8s.io/v1alpha3 auditPolicy: logDir: /var/log/kubernetes/audit @@ -26,6 +25,7 @@ auditPolicy: path: "" certificatesDir: /var/lib/kubernetes/pki clusterName: kubernetes +controlPlaneEndpoint: "" etcd: local: dataDir: /var/lib/etcd diff --git a/cmd/kubeadm/app/util/endpoint.go b/cmd/kubeadm/app/util/endpoint.go index 1e46ad9e6d5..469ae38aef6 100644 --- a/cmd/kubeadm/app/util/endpoint.go +++ b/cmd/kubeadm/app/util/endpoint.go @@ -27,42 +27,42 @@ import ( ) // GetMasterEndpoint returns a properly formatted endpoint for the control plane built according following rules: -// - If the api.ControlPlaneEndpoint is defined, use it. -// - if the api.ControlPlaneEndpoint is defined but without a port number, use the api.ControlPlaneEndpoint + api.BindPort is used. -// - Otherwise, in case the api.ControlPlaneEndpoint is not defined, use the api.AdvertiseAddress + the api.BindPort. -func GetMasterEndpoint(api *kubeadmapi.API) (string, error) { +// - If the ControlPlaneEndpoint is defined, use it. +// - if the ControlPlaneEndpoint is defined but without a port number, use the ControlPlaneEndpoint + api.BindPort is used. +// - Otherwise, in case the ControlPlaneEndpoint is not defined, use the api.AdvertiseAddress + the api.BindPort. +func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) { // parse the bind port - var bindPort = strconv.Itoa(int(api.BindPort)) - if _, err := parsePort(bindPort); err != nil { - return "", fmt.Errorf("invalid value %q given for api.bindPort: %s", api.BindPort, err) + bindPortString := strconv.Itoa(int(cfg.API.BindPort)) + if _, err := ParsePort(bindPortString); err != nil { + return "", fmt.Errorf("invalid value %q given for api.bindPort: %s", cfg.API.BindPort, err) } // parse the AdvertiseAddress - var ip = net.ParseIP(api.AdvertiseAddress) + var ip = net.ParseIP(cfg.API.AdvertiseAddress) if ip == nil { - return "", fmt.Errorf("invalid value `%s` given for api.advertiseAddress", api.AdvertiseAddress) + return "", fmt.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.API.AdvertiseAddress) } // set the master url using cfg.API.AdvertiseAddress + the cfg.API.BindPort masterURL := &url.URL{ Scheme: "https", - Host: net.JoinHostPort(ip.String(), bindPort), + Host: net.JoinHostPort(ip.String(), bindPortString), } // if the controlplane endpoint is defined - if len(api.ControlPlaneEndpoint) > 0 { + if len(cfg.ControlPlaneEndpoint) > 0 { // parse the controlplane endpoint var host, port string var err error - if host, port, err = ParseHostPort(api.ControlPlaneEndpoint); err != nil { - return "", fmt.Errorf("invalid value %q given for api.controlPlaneEndpoint: %s", api.ControlPlaneEndpoint, err) + if host, port, err = ParseHostPort(cfg.ControlPlaneEndpoint); err != nil { + return "", fmt.Errorf("invalid value %q given for controlPlaneEndpoint: %s", cfg.ControlPlaneEndpoint, err) } // if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport if port != "" { - fmt.Println("[endpoint] WARNING: port specified in api.controlPlaneEndpoint overrides api.bindPort in the controlplane address") + fmt.Println("[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address") } else { - port = bindPort + port = bindPortString } // overrides the master url using the controlPlaneAddress (and eventually the bindport) @@ -90,7 +90,7 @@ func ParseHostPort(hostport string) (string, string, error) { // if port is defined, parse and validate it if port != "" { - if _, err := parsePort(port); err != nil { + if _, err := ParsePort(port); err != nil { return "", "", fmt.Errorf("port must be a valid number between 1 and 65535, inclusive") } } @@ -110,8 +110,9 @@ func ParseHostPort(hostport string) (string, string, error) { // ParsePort parses a string representing a TCP port. // If the string is not a valid representation of a TCP port, ParsePort returns an error. -func parsePort(port string) (int, error) { - if portInt, err := strconv.Atoi(port); err == nil && (1 <= portInt && portInt <= 65535) { +func ParsePort(port string) (int, error) { + portInt, err := strconv.Atoi(port) + if err == nil && (1 <= portInt && portInt <= 65535) { return portInt, nil } diff --git a/cmd/kubeadm/app/util/endpoint_test.go b/cmd/kubeadm/app/util/endpoint_test.go index 1bf738c0962..8290cc436eb 100644 --- a/cmd/kubeadm/app/util/endpoint_test.go +++ b/cmd/kubeadm/app/util/endpoint_test.go @@ -25,139 +25,199 @@ import ( func TestGetMasterEndpoint(t *testing.T) { var tests = []struct { name string - api *kubeadmapi.API + cfg *kubeadmapi.InitConfiguration expectedEndpoint string expectedError bool }{ { name: "use ControlPlaneEndpoint (dns) if fully defined", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "cp.k8s.io:1234", - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + ControlPlaneEndpoint: "cp.k8s.io:1234", + }, }, expectedEndpoint: "https://cp.k8s.io:1234", }, { name: "use ControlPlaneEndpoint (ipv4) if fully defined", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "1.2.3.4:1234", - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + ControlPlaneEndpoint: "1.2.3.4:1234", + }, }, expectedEndpoint: "https://1.2.3.4:1234", }, { name: "use ControlPlaneEndpoint (ipv6) if fully defined", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "[2001:db8::1]:1234", - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + ControlPlaneEndpoint: "[2001:db8::1]:1234", + }, }, expectedEndpoint: "https://[2001:db8::1]:1234", }, { name: "use ControlPlaneEndpoint (dns) + BindPort if ControlPlaneEndpoint defined without port", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "cp.k8s.io", - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + ControlPlaneEndpoint: "cp.k8s.io", + }, }, expectedEndpoint: "https://cp.k8s.io:4567", }, { name: "use ControlPlaneEndpoint (ipv4) + BindPort if ControlPlaneEndpoint defined without port", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "1.2.3.4", - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + ControlPlaneEndpoint: "1.2.3.4", + }, }, expectedEndpoint: "https://1.2.3.4:4567", }, { name: "use ControlPlaneEndpoint (ipv6) + BindPort if ControlPlaneEndpoint defined without port", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "2001:db8::1", - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + ControlPlaneEndpoint: "2001:db8::1", + }, }, expectedEndpoint: "https://[2001:db8::1]:4567", }, { name: "use AdvertiseAddress (ipv4) + BindPort if ControlPlaneEndpoint is not defined", - api: &kubeadmapi.API{ - BindPort: 4567, - AdvertiseAddress: "4.5.6.7", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "4.5.6.7", + }, + }, }, expectedEndpoint: "https://4.5.6.7:4567", }, { name: "use AdvertiseAddress (ipv6) + BindPort if ControlPlaneEndpoint is not defined", - api: &kubeadmapi.API{ - BindPort: 4567, - AdvertiseAddress: "2001:db8::1", + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + AdvertiseAddress: "2001:db8::1", + }, + }, }, expectedEndpoint: "https://[2001:db8::1]:4567", }, { name: "fail if invalid BindPort", - api: &kubeadmapi.API{ - BindPort: 0, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 0, + }, + }, }, expectedError: true, }, { name: "fail if invalid ControlPlaneEndpoint (dns)", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "bad!!.cp.k8s.io", - BindPort: 4567, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + }, + ControlPlaneEndpoint: "bad!!.cp.k8s.io", + }, }, expectedError: true, }, { name: "fail if invalid ControlPlaneEndpoint (ip4)", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "1..0", - BindPort: 4567, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + }, + ControlPlaneEndpoint: "1..0", + }, }, expectedError: true, }, { name: "fail if invalid ControlPlaneEndpoint (ip6)", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313", - BindPort: 4567, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + }, + ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313", + }, }, expectedError: true, }, { name: "fail if invalid ControlPlaneEndpoint (port)", - api: &kubeadmapi.API{ - ControlPlaneEndpoint: "cp.k8s.io:0", - BindPort: 4567, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + BindPort: 4567, + }, + ControlPlaneEndpoint: "cp.k8s.io:0", + }, }, expectedError: true, }, { name: "fail if invalid AdvertiseAddress (ip4)", - api: &kubeadmapi.API{ - AdvertiseAddress: "1..0", - BindPort: 4567, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + AdvertiseAddress: "1..0", + BindPort: 4567, + }, + }, }, expectedError: true, }, { name: "fail if invalid AdvertiseAddress (ip6)", - api: &kubeadmapi.API{ - AdvertiseAddress: "1200::AB00:1234::2552:7777:1313", - BindPort: 4567, + cfg: &kubeadmapi.InitConfiguration{ + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{ + AdvertiseAddress: "1200::AB00:1234::2552:7777:1313", + BindPort: 4567, + }, + }, }, expectedError: true, }, } for _, rt := range tests { - actualEndpoint, actualError := GetMasterEndpoint(rt.api) + actualEndpoint, actualError := GetMasterEndpoint(rt.cfg) if (actualError != nil) && !rt.expectedError { t.Errorf("%s unexpected failure: %v", rt.name, actualError) @@ -328,7 +388,7 @@ func TestParsePort(t *testing.T) { } for _, rt := range tests { - actualPort, actualError := parsePort(rt.port) + actualPort, actualError := ParsePort(rt.port) if (actualError != nil) && !rt.expectedError { t.Errorf("%s unexpected failure: %v", rt.name, actualError)