Merge pull request #67441 from rosti/kubeadm_clusterconfig

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

[reissue] kubeadm: Split out ClusterConfiguration from InitConfiguration

As @luxas is not able to take care of #66219, I am reissuing the same change here. There are a few minor things added by me:

- The original PR is rebased on latest master.
- Some broken tests were fixed.
- Some TODOs were added.
- Run update-bazel and update-gofmt

Below is the text of the original PR by Lucas.

-----

**What this PR does / why we need it:**

Splits MasterConfiguration to InitConfiguration and ClusterConfiguration as outlined in the kubeadm Config KEP. InitConfiguration holds init-only information, and ClusterConfiguration holds cluster-wide information. In the internal representation InitConfiguration wraps ClusterConfiguration as a field, but in serialized format they're different YAML documents.

**Which issue(s) this PR fixes** (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
ref: kubernetes/kubeadm#911
Depends on:

- [X] #65776
- [X] #65628
- [X] #65629
- [X] #65631
- [X] #65940
- [X] #65787
- [X] #65945
- [X] #65951
- [X] #65952

**Special notes for your reviewer:**

**Release note**:
```release-note
kubeadm: InitConfiguration now consists of two structs: InitConfiguration and ClusterConfiguration
```

@kubernetes/sig-cluster-lifecycle-pr-reviews
This commit is contained in:
Kubernetes Submit Queue
2018-08-22 16:46:59 -07:00
committed by GitHub
60 changed files with 1380 additions and 959 deletions

View File

@@ -42,8 +42,4 @@ go_test(
name = "go_default_test",
srcs = ["fuzzer_test.go"],
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/roundtrip:go_default_library",
],
)

View File

@@ -33,18 +33,18 @@ import (
utilpointer "k8s.io/utils/pointer"
)
// NOTE: Right now this code is unused, as the test utilizing this is disabled.
// Funcs returns the fuzzer functions for the kubeadm apis.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{
func(obj *kubeadm.ClusterConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
fuzzClusterConfig(obj)
},
func(obj *kubeadm.InitConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
obj.KubernetesVersion = "v10"
obj.API.BindPort = 20
obj.API.AdvertiseAddress = "foo"
obj.Networking.ServiceSubnet = "10.96.0.0/12"
obj.Networking.DNSDomain = "cluster.local"
obj.CertificatesDir = "foo"
obj.APIServerCertSANs = []string{"foo"}
fuzzClusterConfig(&obj.ClusterConfiguration)
obj.BootstrapTokens = []kubeadm.BootstrapToken{
{
Token: &kubeadm.BootstrapTokenString{
@@ -56,47 +56,11 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
Groups: []string{"foo"},
},
}
obj.ImageRepository = "foo"
obj.CIImageRepository = ""
obj.UnifiedControlPlaneImage = "foo"
obj.FeatureGates = map[string]bool{"foo": true}
obj.ClusterName = "foo"
obj.APIServerExtraArgs = map[string]string{"foo": "foo"}
obj.APIServerExtraVolumes = []kubeadm.HostPathMount{{
Name: "foo",
HostPath: "foo",
MountPath: "foo",
Writable: false,
}}
obj.Etcd.Local = &kubeadm.LocalEtcd{
Image: "foo",
DataDir: "foo",
ServerCertSANs: []string{"foo"},
PeerCertSANs: []string{"foo"},
ExtraArgs: map[string]string{"foo": "foo"},
}
obj.NodeRegistration = kubeadm.NodeRegistrationOptions{
CRISocket: "foo",
Name: "foo",
Taints: []v1.Taint{},
}
obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{
Path: "foo",
LogDir: "/foo",
LogMaxAge: utilpointer.Int32Ptr(0),
}
// Set the Kubelet ComponentConfig to an empty, defaulted struct
extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{}
obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
componentconfigs.Scheme.Default(extkubeletconfig)
componentconfigs.Scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil)
componentconfigs.DefaultKubeletConfiguration(obj)
// Set the KubeProxy ComponentConfig to an empty, defaulted struct
extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
componentconfigs.Scheme.Default(extkubeproxyconfig)
componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil)
componentconfigs.DefaultKubeProxyConfiguration(obj)
},
func(obj *kubeadm.JoinConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
@@ -115,3 +79,49 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
},
}
}
func fuzzClusterConfig(obj *kubeadm.ClusterConfiguration) {
obj.KubernetesVersion = "v10"
obj.API.BindPort = 20
obj.API.AdvertiseAddress = "foo"
obj.Networking.ServiceSubnet = "10.96.0.0/12"
obj.Networking.DNSDomain = "cluster.local"
obj.CertificatesDir = "foo"
obj.APIServerCertSANs = []string{"foo"}
obj.ImageRepository = "foo"
obj.CIImageRepository = ""
obj.UnifiedControlPlaneImage = "foo"
obj.FeatureGates = map[string]bool{"foo": true}
obj.ClusterName = "foo"
obj.APIServerExtraArgs = map[string]string{"foo": "foo"}
obj.APIServerExtraVolumes = []kubeadm.HostPathMount{{
Name: "foo",
HostPath: "foo",
MountPath: "foo",
Writable: false,
}}
obj.Etcd.Local = &kubeadm.LocalEtcd{
Image: "foo",
DataDir: "foo",
ServerCertSANs: []string{"foo"},
PeerCertSANs: []string{"foo"},
ExtraArgs: map[string]string{"foo": "foo"},
}
obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{
Path: "foo",
LogDir: "/foo",
LogMaxAge: utilpointer.Int32Ptr(0),
}
// Set the Kubelet ComponentConfig to an empty, defaulted struct
extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{}
obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{}
componentconfigs.Scheme.Default(extkubeletconfig)
componentconfigs.Scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil)
componentconfigs.DefaultKubeletConfiguration(obj)
// Set the KubeProxy ComponentConfig to an empty, defaulted struct
extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{}
componentconfigs.Scheme.Default(extkubeproxyconfig)
componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil)
componentconfigs.DefaultKubeProxyConfiguration(obj)
}

View File

@@ -16,7 +16,12 @@ limitations under the License.
package fuzzer
import (
// TODO: Fuzzing rouudtrip tests are currently disabled in the v1.12 cycle due to the
// v1alpha2 -> v1alpha3 migration. As the ComponentConfigs were embedded in the structs
// earlier now have moved out it's not possible to do a lossless roundtrip "the normal way"
// When we support v1alpha3 and higher only, we can reenable this
/*import (
"testing"
"k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
@@ -25,4 +30,4 @@ import (
func TestRoundTripTypes(t *testing.T) {
roundtrip.RoundTripTestForAPIGroup(t, scheme.AddToScheme, Funcs)
}
}*/

View File

@@ -47,6 +47,7 @@ func Resource(resource string) schema.GroupResource {
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&InitConfiguration{},
&ClusterConfiguration{},
&JoinConfiguration{},
)
return nil

View File

@@ -19,7 +19,7 @@ package kubeadm
import (
fuzz "github.com/google/gofuzz"
v1 "k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
@@ -27,30 +27,38 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// InitConfiguration contains a list of elements which make up master's
// configuration object.
// InitConfiguration contains a list of fields that are specifically "kubeadm init"-only runtime
// information. The cluster-wide config is stored in ClusterConfiguration. The InitConfiguration
// object IS NOT uploaded to the kubeadm-config ConfigMap in the cluster, only the
// ClusterConfiguration is.
type InitConfiguration struct {
metav1.TypeMeta
// `kubeadm init`-only information. These fields are solely used the first time `kubeadm init` runs.
// After that, the information in the fields ARE NOT uploaded to the `kubeadm-config` ConfigMap
// that is used by `kubeadm upgrade` for instance.
// ClusterConfiguration holds the cluster-wide information, and embeds that struct (which can be (un)marshalled separately as well)
// When InitConfiguration is marshalled to bytes in the external version, this information IS NOT preserved (which can be seen from
// the `json:"-"` tag in the external variant of these API types. Here, in the internal version `json:",inline"` is used, which means
// that all of ClusterConfiguration's fields will appear as they would be InitConfiguration's fields. This is used in practice solely
// in kubeadm API roundtrip unit testing. Check out `cmd/kubeadm/app/util/config/*_test.go` for more information. Normally, the internal
// type is NEVER marshalled, but always converted to some external version first.
ClusterConfiguration `json:",inline"`
// BootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create.
// This information IS NOT uploaded to the kubeadm cluster configmap, partly because of its sensitive nature
BootstrapTokens []BootstrapToken
// NodeRegistration holds fields that relate to registering the new master node to the cluster
NodeRegistration NodeRegistrationOptions
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster
type ClusterConfiguration struct {
metav1.TypeMeta
// ComponentConfigs holds internal ComponentConfig struct types known to kubeadm, should long-term only exist in the internal kubeadm API
// +k8s:conversion-gen=false
ComponentConfigs ComponentConfigs
// Cluster-wide configuration
// TODO: Move these fields under some kind of ClusterConfiguration or similar struct that describes
// one cluster. Eventually we want this kind of spec to align well with the Cluster API spec.
// API holds configuration for the k8s apiserver.
API API
// Etcd holds configuration for etcd.
@@ -254,7 +262,6 @@ type ExternalEtcd struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// JoinConfiguration contains elements describing a particular node.
// TODO: This struct should be replaced by dynamic kubelet configuration.
type JoinConfiguration struct {
metav1.TypeMeta

View File

@@ -17,6 +17,8 @@ limitations under the License.
package v1alpha2
import (
"unsafe"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
@@ -50,6 +52,31 @@ func Convert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitCon
}
}
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
}
@@ -76,5 +103,32 @@ func Convert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kubeadm
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
}

View File

@@ -351,68 +351,34 @@ func autoConvert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(in *Ini
if err := Convert_v1alpha2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err
}
if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
return err
}
// WARNING: in.API requires manual conversion: does not exist in peer-type
// WARNING: in.KubeProxy requires manual conversion: does not exist in peer-type
if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
return err
}
// WARNING: in.Etcd requires manual conversion: does not exist in peer-type
// WARNING: in.KubeletConfiguration requires manual conversion: does not exist in peer-type
if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil {
return err
}
out.KubernetesVersion = in.KubernetesVersion
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
if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil {
return err
}
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
out.ClusterName = in.ClusterName
// WARNING: in.Networking requires manual conversion: does not exist in peer-type
// WARNING: in.KubernetesVersion requires manual conversion: does not exist in peer-type
// WARNING: in.APIServerExtraArgs requires manual conversion: does not exist in peer-type
// WARNING: in.ControllerManagerExtraArgs requires manual conversion: does not exist in peer-type
// WARNING: in.SchedulerExtraArgs requires manual conversion: does not exist in peer-type
// WARNING: in.APIServerExtraVolumes requires manual conversion: does not exist in peer-type
// WARNING: in.ControllerManagerExtraVolumes requires manual conversion: does not exist in peer-type
// WARNING: in.SchedulerExtraVolumes requires manual conversion: does not exist in peer-type
// WARNING: in.APIServerCertSANs requires manual conversion: does not exist in peer-type
// WARNING: in.CertificatesDir requires manual conversion: does not exist in peer-type
// WARNING: in.ImageRepository requires manual conversion: does not exist in peer-type
// WARNING: in.UnifiedControlPlaneImage requires manual conversion: does not exist in peer-type
// WARNING: in.AuditPolicyConfiguration requires manual conversion: does not exist in peer-type
// WARNING: in.FeatureGates requires manual conversion: does not exist in peer-type
// WARNING: in.ClusterName requires manual conversion: does not exist in peer-type
return nil
}
func autoConvert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error {
// WARNING: in.ClusterConfiguration requires manual conversion: does not exist in peer-type
out.BootstrapTokens = *(*[]BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens))
if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err
}
// INFO: in.ComponentConfigs opted out of conversion generation
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
}
out.KubernetesVersion = in.KubernetesVersion
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
// INFO: in.CIImageRepository opted out of conversion generation
out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage
if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha2_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil {
return err
}
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
out.ClusterName = in.ClusterName
return nil
}

View File

@@ -28,8 +28,8 @@ import (
kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1"
)
func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
if err := autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s); err != nil {
func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error {
if err := autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s); err != nil {
return err
}
@@ -60,7 +60,7 @@ func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitCon
return nil
}
func defaultKubeProxyConfiguration(internalcfg *InitConfiguration, obj *kubeproxyconfig.KubeProxyConfiguration) {
func defaultKubeProxyConfiguration(internalcfg *ClusterConfiguration, obj *kubeproxyconfig.KubeProxyConfiguration) {
// NOTE: This code should be mirrored from cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go and cmd/kubeadm/app/componentconfig/defaults.go
if obj.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" {
obj.ClusterCIDR = internalcfg.Networking.PodSubnet
@@ -71,7 +71,7 @@ func defaultKubeProxyConfiguration(internalcfg *InitConfiguration, obj *kubeprox
}
}
func defaultKubeletConfiguration(internalcfg *InitConfiguration, obj *kubeletconfig.KubeletConfiguration) {
func defaultKubeletConfiguration(internalcfg *ClusterConfiguration, obj *kubeletconfig.KubeletConfiguration) {
// NOTE: This code should be mirrored from cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go and cmd/kubeadm/app/componentconfig/defaults.go
if obj.StaticPodPath == "" {
obj.StaticPodPath = DefaultManifestsDir

View File

@@ -67,8 +67,15 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
return RegisterDefaults(scheme)
}
// SetDefaults_InitConfiguration assigns default values to Master node
// SetDefaults_InitConfiguration assigns default values for the InitConfiguration
func SetDefaults_InitConfiguration(obj *InitConfiguration) {
SetDefaults_ClusterConfiguration(&obj.ClusterConfiguration)
SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration)
SetDefaults_BootstrapTokens(obj)
}
// SetDefaults_ClusterConfiguration assigns default values for the ClusterConfiguration
func SetDefaults_ClusterConfiguration(obj *ClusterConfiguration) {
if obj.KubernetesVersion == "" {
obj.KubernetesVersion = DefaultKubernetesVersion
}
@@ -97,14 +104,12 @@ func SetDefaults_InitConfiguration(obj *InitConfiguration) {
obj.ClusterName = DefaultClusterName
}
SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration)
SetDefaults_BootstrapTokens(obj)
SetDefaults_Etcd(obj)
SetDefaults_AuditPolicyConfiguration(obj)
}
// SetDefaults_Etcd assigns default values for the Proxy
func SetDefaults_Etcd(obj *InitConfiguration) {
func SetDefaults_Etcd(obj *ClusterConfiguration) {
if obj.Etcd.External == nil && obj.Etcd.Local == nil {
obj.Etcd.Local = &LocalEtcd{}
}
@@ -152,7 +157,7 @@ func SetDefaults_NodeRegistrationOptions(obj *NodeRegistrationOptions) {
}
// SetDefaults_AuditPolicyConfiguration sets default values for the AuditPolicyConfiguration
func SetDefaults_AuditPolicyConfiguration(obj *InitConfiguration) {
func SetDefaults_AuditPolicyConfiguration(obj *ClusterConfiguration) {
if obj.AuditPolicyConfiguration.LogDir == "" {
obj.AuditPolicyConfiguration.LogDir = constants.StaticPodAuditPolicyLogDir
}

View File

@@ -59,6 +59,7 @@ func Resource(resource string) schema.GroupResource {
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&InitConfiguration{},
&ClusterConfiguration{},
&JoinConfiguration{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)

View File

@@ -23,11 +23,17 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// InitConfiguration contains a list of elements which make up master's
// configuration object.
// InitConfiguration contains a list of elements that is specific "kubeadm init"-only runtime
// information.
type InitConfiguration struct {
metav1.TypeMeta `json:",inline"`
// ClusterConfiguration holds the cluster-wide information, and embeds that struct (which can be (un)marshalled separately as well)
// When InitConfiguration is marshalled to bytes in the external version, this information IS NOT preserved (which can be seen from
// the `json:"-"` tag. This is due to that when InitConfiguration is (un)marshalled, it turns into two YAML documents, one for the
// InitConfiguration and ClusterConfiguration. Hence, the information must not be duplicated, and is therefore omitted here.
ClusterConfiguration `json:"-"`
// `kubeadm init`-only information. These fields are solely used the first time `kubeadm init` runs.
// After that, the information in the fields ARE NOT uploaded to the `kubeadm-config` ConfigMap
// that is used by `kubeadm upgrade` for instance. These fields must be omitempty.
@@ -38,10 +44,13 @@ type InitConfiguration struct {
// NodeRegistration holds fields that relate to registering the new master node to the cluster
NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"`
}
// Cluster-wide configuration
// TODO: Move these fields under some kind of ClusterConfiguration or similar struct that describes
// one cluster. Eventually we want this kind of spec to align well with the Cluster API spec.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster
type ClusterConfiguration struct {
metav1.TypeMeta `json:",inline"`
// API holds configuration for the k8s apiserver.
API API `json:"api"`

View File

@@ -77,6 +77,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kubeadm.ClusterConfiguration)(nil), (*ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(a.(*kubeadm.ClusterConfiguration), b.(*ClusterConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Etcd)(nil), (*kubeadm.Etcd)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_Etcd_To_kubeadm_Etcd(a.(*Etcd), b.(*kubeadm.Etcd), scope)
}); err != nil {
@@ -157,8 +167,8 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope)
if err := s.AddConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope)
}); err != nil {
return err
}
@@ -265,6 +275,71 @@ func Convert_kubeadm_BootstrapTokenString_To_v1alpha3_BootstrapTokenString(in *k
return autoConvert_kubeadm_BootstrapTokenString_To_v1alpha3_BootstrapTokenString(in, out, s)
}
func autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error {
if err := Convert_v1alpha3_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
return err
}
if err := Convert_v1alpha3_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
return err
}
if err := Convert_v1alpha3_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil {
return err
}
out.KubernetesVersion = in.KubernetesVersion
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
if err := Convert_v1alpha3_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil {
return err
}
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
out.ClusterName = in.ClusterName
return nil
}
func autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error {
// INFO: in.ComponentConfigs opted out of conversion generation
if err := Convert_kubeadm_API_To_v1alpha3_API(&in.API, &out.API, s); err != nil {
return err
}
if err := Convert_kubeadm_Etcd_To_v1alpha3_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
return err
}
if err := Convert_kubeadm_Networking_To_v1alpha3_Networking(&in.Networking, &out.Networking, s); err != nil {
return err
}
out.KubernetesVersion = in.KubernetesVersion
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
// INFO: in.CIImageRepository opted out of conversion generation
out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage
if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha3_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil {
return err
}
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
out.ClusterName = in.ClusterName
return nil
}
// Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration is an autogenerated conversion function.
func Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error {
return autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in, out, s)
}
func autoConvert_v1alpha3_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s conversion.Scope) error {
out.Local = (*kubeadm.LocalEtcd)(unsafe.Pointer(in.Local))
out.External = (*kubeadm.ExternalEtcd)(unsafe.Pointer(in.External))
@@ -342,70 +417,29 @@ func Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPat
}
func autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
if err := Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil {
return err
}
out.BootstrapTokens = *(*[]kubeadm.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens))
if err := Convert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err
}
if err := Convert_v1alpha3_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
return err
}
if err := Convert_v1alpha3_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
return err
}
if err := Convert_v1alpha3_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil {
return err
}
out.KubernetesVersion = in.KubernetesVersion
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
if err := Convert_v1alpha3_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil {
return err
}
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
out.ClusterName = in.ClusterName
return nil
}
// Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration is an autogenerated conversion function.
func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
return autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s)
}
func autoConvert_kubeadm_InitConfiguration_To_v1alpha3_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error {
if err := Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil {
return err
}
out.BootstrapTokens = *(*[]BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens))
if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err
}
// INFO: in.ComponentConfigs opted out of conversion generation
if err := Convert_kubeadm_API_To_v1alpha3_API(&in.API, &out.API, s); err != nil {
return err
}
if err := Convert_kubeadm_Etcd_To_v1alpha3_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
return err
}
if err := Convert_kubeadm_Networking_To_v1alpha3_Networking(&in.Networking, &out.Networking, s); err != nil {
return err
}
out.KubernetesVersion = in.KubernetesVersion
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
// INFO: in.CIImageRepository opted out of conversion generation
out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage
if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha3_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil {
return err
}
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
out.ClusterName = in.ClusterName
return nil
}

View File

@@ -119,6 +119,83 @@ func (in *BootstrapTokenString) DeepCopy() *BootstrapTokenString {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
out.API = in.API
in.Etcd.DeepCopyInto(&out.Etcd)
out.Networking = in.Networking
if in.APIServerExtraArgs != nil {
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.ControllerManagerExtraArgs != nil {
in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.SchedulerExtraArgs != nil {
in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.APIServerExtraVolumes != nil {
in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.ControllerManagerExtraVolumes != nil {
in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.SchedulerExtraVolumes != nil {
in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.APIServerCertSANs != nil {
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
*out = make([]string, len(*in))
copy(*out, *in)
}
in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration)
if in.FeatureGates != nil {
in, out := &in.FeatureGates, &out.FeatureGates
*out = make(map[string]bool, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfiguration.
func (in *ClusterConfiguration) DeepCopy() *ClusterConfiguration {
if in == nil {
return nil
}
out := new(ClusterConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Etcd) DeepCopyInto(out *Etcd) {
*out = *in
@@ -186,6 +263,7 @@ func (in *HostPathMount) DeepCopy() *HostPathMount {
func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ClusterConfiguration.DeepCopyInto(&out.ClusterConfiguration)
if in.BootstrapTokens != nil {
in, out := &in.BootstrapTokens, &out.BootstrapTokens
*out = make([]BootstrapToken, len(*in))
@@ -194,58 +272,6 @@ func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) {
}
}
in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
out.API = in.API
in.Etcd.DeepCopyInto(&out.Etcd)
out.Networking = in.Networking
if in.APIServerExtraArgs != nil {
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.ControllerManagerExtraArgs != nil {
in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.SchedulerExtraArgs != nil {
in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.APIServerExtraVolumes != nil {
in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.ControllerManagerExtraVolumes != nil {
in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.SchedulerExtraVolumes != nil {
in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.APIServerCertSANs != nil {
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
*out = make([]string, len(*in))
copy(*out, *in)
}
in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration)
if in.FeatureGates != nil {
in, out := &in.FeatureGates, &out.FeatureGates
*out = make(map[string]bool, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}

View File

@@ -28,13 +28,19 @@ import (
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&ClusterConfiguration{}, func(obj interface{}) { SetObjectDefaults_ClusterConfiguration(obj.(*ClusterConfiguration)) })
scheme.AddTypeDefaultingFunc(&InitConfiguration{}, func(obj interface{}) { SetObjectDefaults_InitConfiguration(obj.(*InitConfiguration)) })
scheme.AddTypeDefaultingFunc(&JoinConfiguration{}, func(obj interface{}) { SetObjectDefaults_JoinConfiguration(obj.(*JoinConfiguration)) })
return nil
}
func SetObjectDefaults_ClusterConfiguration(in *ClusterConfiguration) {
SetDefaults_ClusterConfiguration(in)
}
func SetObjectDefaults_InitConfiguration(in *InitConfiguration) {
SetDefaults_InitConfiguration(in)
SetObjectDefaults_ClusterConfiguration(&in.ClusterConfiguration)
for i := range in.BootstrapTokens {
a := &in.BootstrapTokens[i]
SetDefaults_BootstrapToken(a)

View File

@@ -41,14 +41,21 @@ import (
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
)
// ValidateInitConfiguration validates master configuration and collects all encountered errors
// ValidateInitConfiguration validates an InitConfiguration object and collects all encountered errors
func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateNodeRegistrationOptions(&c.NodeRegistration, field.NewPath("nodeRegistration"))...)
allErrs = append(allErrs, ValidateBootstrapTokens(c.BootstrapTokens, field.NewPath("bootstrapTokens"))...)
allErrs = append(allErrs, ValidateClusterConfiguration(&c.ClusterConfiguration)...)
return allErrs
}
// ValidateClusterConfiguration validates an ClusterConfiguration object and collects all encountered errors
func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
allErrs = append(allErrs, ValidateCertSANs(c.APIServerCertSANs, field.NewPath("apiServerCertSANs"))...)
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificatesDir"))...)
allErrs = append(allErrs, ValidateNodeRegistrationOptions(&c.NodeRegistration, field.NewPath("nodeRegistration"))...)
allErrs = append(allErrs, ValidateBootstrapTokens(c.BootstrapTokens, field.NewPath("bootstrapTokens"))...)
allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...)
allErrs = append(allErrs, ValidateAPIEndpoint(&c.API, field.NewPath("api"))...)
allErrs = append(allErrs, ValidateEtcd(&c.Etcd, field.NewPath("etcd"))...)

View File

@@ -232,10 +232,12 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid DNS ControlPlaneEndpoint (with port), AdvertiseAddress and default port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "cp.k8s.io:8081",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "cp.k8s.io:8081",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
},
},
},
expected: true,
@@ -243,10 +245,12 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid IPv4 ControlPlaneEndpoint (with port), AdvertiseAddress and default port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1.2.3.4:8081",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1.2.3.4:8081",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
},
},
},
expected: true,
@@ -254,10 +258,12 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid IPv6 ControlPlaneEndpoint (with port), ControlPlaneEndpoint and port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "[2001:db7::1]:8081",
AdvertiseAddress: "2001:db7::2",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "[2001:db7::1]:8081",
AdvertiseAddress: "2001:db7::2",
BindPort: 6443,
},
},
},
expected: true,
@@ -265,10 +271,12 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid DNS ControlPlaneEndpoint (without port), AdvertiseAddress and default port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "cp.k8s.io",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "cp.k8s.io",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
},
},
},
expected: true,
@@ -276,10 +284,12 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid IPv4 ControlPlaneEndpoint (without port), AdvertiseAddress and default port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1.2.3.4",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1.2.3.4",
AdvertiseAddress: "4.5.6.7",
BindPort: 6443,
},
},
},
expected: true,
@@ -287,10 +297,12 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid IPv6 ControlPlaneEndpoint (without port), ControlPlaneEndpoint and port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "2001:db7::1",
AdvertiseAddress: "2001:db7::2",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "2001:db7::1",
AdvertiseAddress: "2001:db7::2",
BindPort: 6443,
},
},
},
expected: true,
@@ -298,9 +310,11 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid IPv4 AdvertiseAddress and default port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
},
},
expected: true,
@@ -308,9 +322,11 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Valid IPv6 AdvertiseAddress and port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "2001:db7::1",
BindPort: 3446,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "2001:db7::1",
BindPort: 3446,
},
},
},
expected: true,
@@ -318,9 +334,11 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid IPv4 AdvertiseAddress",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.34",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.34",
BindPort: 6443,
},
},
},
expected: false,
@@ -328,9 +346,11 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid IPv6 AdvertiseAddress",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "2001:db7:1",
BindPort: 3446,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "2001:db7:1",
BindPort: 3446,
},
},
},
expected: false,
@@ -338,9 +358,11 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid BindPort",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 0,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 0,
},
},
},
expected: false,
@@ -348,8 +370,10 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid DNS ControlPlaneEndpoint",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "bad!!.k8s.io",
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "bad!!.k8s.io",
},
},
},
expected: false,
@@ -357,8 +381,10 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid ipv4 ControlPlaneEndpoint",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1..3.4",
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1..3.4",
},
},
},
expected: false,
@@ -366,8 +392,10 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid ipv6 ControlPlaneEndpoint",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313",
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313",
},
},
},
expected: false,
@@ -375,8 +403,10 @@ func TestValidateAPIEndpoint(t *testing.T) {
{
name: "Invalid ControlPlaneEndpoint port",
s: &kubeadm.InitConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1.2.3.4:0",
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
ControlPlaneEndpoint: "1.2.3.4:0",
},
},
},
expected: false,
@@ -406,143 +436,155 @@ func TestValidateInitConfiguration(t *testing.T) {
&kubeadm.InitConfiguration{}, false},
{"invalid missing token with IPv4 service subnet",
&kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"},
}, false},
{"invalid missing token with IPv6 service subnet",
&kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Networking: kubeadm.Networking{
ServiceSubnet: "2001:db8::1/98",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "2001:db8::1/98",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"},
}, false},
{"invalid missing node name",
&kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/other/cert/dir",
}, false},
{"valid master configuration with incorrect IPv4 pod subnet",
&kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15",
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15",
},
CertificatesDir: "/some/other/cert/dir",
NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"},
}, false},
{"valid master configuration with IPv4 service subnet",
&kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
},
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: utilpointer.Int32Ptr(2),
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
},
},
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: utilpointer.Int32Ptr(2),
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15/16",
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15/16",
},
CertificatesDir: "/some/other/cert/dir",
NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"},
}, true},
{"valid master configuration using IPv6 service subnet",
&kubeadm.InitConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1:2:3::4",
BindPort: 3446,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
ClusterConfiguration: kubeadm.ClusterConfiguration{
API: kubeadm.API{
AdvertiseAddress: "1:2:3::4",
BindPort: 3446,
},
},
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: utilpointer.Int32Ptr(2),
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
},
},
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24",
UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeAll: true,
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: utilpointer.Int32Ptr(2),
MaxPerCore: utilpointer.Int32Ptr(1),
Min: utilpointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
},
Networking: kubeadm.Networking{
ServiceSubnet: "2001:db8::1/98",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "2001:db8::1/98",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/other/cert/dir",
NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"},
}, true},
}

View File

@@ -121,6 +121,84 @@ func (in *BootstrapTokenString) DeepCopy() *BootstrapTokenString {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ComponentConfigs.DeepCopyInto(&out.ComponentConfigs)
out.API = in.API
in.Etcd.DeepCopyInto(&out.Etcd)
out.Networking = in.Networking
if in.APIServerExtraArgs != nil {
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.ControllerManagerExtraArgs != nil {
in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.SchedulerExtraArgs != nil {
in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.APIServerExtraVolumes != nil {
in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.ControllerManagerExtraVolumes != nil {
in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.SchedulerExtraVolumes != nil {
in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.APIServerCertSANs != nil {
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
*out = make([]string, len(*in))
copy(*out, *in)
}
in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration)
if in.FeatureGates != nil {
in, out := &in.FeatureGates, &out.FeatureGates
*out = make(map[string]bool, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfiguration.
func (in *ClusterConfiguration) DeepCopy() *ClusterConfiguration {
if in == nil {
return nil
}
out := new(ClusterConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ClusterConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentConfigs) DeepCopyInto(out *ComponentConfigs) {
*out = *in
@@ -214,6 +292,7 @@ func (in *HostPathMount) DeepCopy() *HostPathMount {
func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ClusterConfiguration.DeepCopyInto(&out.ClusterConfiguration)
if in.BootstrapTokens != nil {
in, out := &in.BootstrapTokens, &out.BootstrapTokens
*out = make([]BootstrapToken, len(*in))
@@ -222,59 +301,6 @@ func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) {
}
}
in.NodeRegistration.DeepCopyInto(&out.NodeRegistration)
in.ComponentConfigs.DeepCopyInto(&out.ComponentConfigs)
out.API = in.API
in.Etcd.DeepCopyInto(&out.Etcd)
out.Networking = in.Networking
if in.APIServerExtraArgs != nil {
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.ControllerManagerExtraArgs != nil {
in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.SchedulerExtraArgs != nil {
in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.APIServerExtraVolumes != nil {
in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.ControllerManagerExtraVolumes != nil {
in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.SchedulerExtraVolumes != nil {
in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes
*out = make([]HostPathMount, len(*in))
copy(*out, *in)
}
if in.APIServerCertSANs != nil {
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
*out = make([]string, len(*in))
copy(*out, *in)
}
in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration)
if in.FeatureGates != nil {
in, out := &in.FeatureGates, &out.FeatureGates
*out = make(map[string]bool, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}

View File

@@ -126,7 +126,10 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
switch apiObject {
case constants.InitConfigurationKind, constants.MasterConfigurationKind:
return getDefaultInitConfigBytes()
return getDefaultInitConfigBytes(constants.InitConfigurationKind)
case constants.ClusterConfigurationKind:
return getDefaultInitConfigBytes(constants.ClusterConfigurationKind)
case constants.JoinConfigurationKind, constants.NodeConfigurationKind:
return getDefaultNodeConfigBytes()
@@ -143,7 +146,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
// getSupportedAPIObjects returns all currently supported API object names
func getSupportedAPIObjects() []string {
objects := []string{constants.InitConfigurationKind, constants.JoinConfigurationKind}
objects := []string{constants.InitConfigurationKind, constants.ClusterConfigurationKind, constants.JoinConfigurationKind}
for componentType := range componentconfigs.Known {
objects = append(objects, string(componentType))
}
@@ -160,19 +163,31 @@ func getAllAPIObjectNames() []string {
func getDefaultedInitConfig() (*kubeadmapi.InitConfiguration, error) {
return configutil.ConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1alpha3.InitConfiguration{
API: kubeadmapiv1alpha3.API{AdvertiseAddress: "1.2.3.4"},
BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{sillyToken},
KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1),
// TODO: Probably move to getDefaultedClusterConfig?
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
API: kubeadmapiv1alpha3.API{AdvertiseAddress: "1.2.3.4"},
KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1),
},
BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{sillyToken},
})
}
func getDefaultInitConfigBytes() ([]byte, error) {
// TODO: This is now invoked for both InitConfiguration and ClusterConfiguration, we should make separate versions of it
func getDefaultInitConfigBytes(kind string) ([]byte, error) {
internalcfg, err := getDefaultedInitConfig()
if err != nil {
return []byte{}, err
}
return configutil.MarshalKubeadmConfigObject(internalcfg)
b, err := configutil.MarshalKubeadmConfigObject(internalcfg)
if err != nil {
return []byte{}, err
}
gvkmap, err := kubeadmutil.SplitYAMLDocuments(b)
if err != nil {
return []byte{}, err
}
return gvkmap[kubeadmapiv1alpha3.SchemeGroupVersion.WithKind(kind)], nil
}
func getDefaultNodeConfigBytes() ([]byte, error) {
@@ -194,7 +209,7 @@ func getDefaultComponentConfigBytes(registration componentconfigs.Registration)
return []byte{}, err
}
realobj, ok := registration.GetFromInternalConfig(defaultedInitConfig)
realobj, ok := registration.GetFromInternalConfig(&defaultedInitConfig.ClusterConfiguration)
if !ok {
return []byte{}, fmt.Errorf("GetFromInternalConfig failed")
}
@@ -404,8 +419,8 @@ func NewCmdConfigImages(out io.Writer) *cobra.Command {
// NewCmdConfigImagesPull returns the `kubeadm config images pull` command
func NewCmdConfigImagesPull() *cobra.Command {
cfg := &kubeadmapiv1alpha3.InitConfiguration{}
kubeadmscheme.Scheme.Default(cfg)
externalcfg := &kubeadmapiv1alpha3.InitConfiguration{}
kubeadmscheme.Scheme.Default(externalcfg)
var cfgPath, featureGatesString string
var err error
@@ -413,9 +428,9 @@ func NewCmdConfigImagesPull() *cobra.Command {
Use: "pull",
Short: "Pull images used by kubeadm.",
Run: func(_ *cobra.Command, _ []string) {
cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
kubeadmutil.CheckErr(err)
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, externalcfg)
kubeadmutil.CheckErr(err)
containerRuntime, err := utilruntime.NewContainerRuntime(utilsexec.New(), internalcfg.GetCRISocket())
kubeadmutil.CheckErr(err)
@@ -423,8 +438,8 @@ func NewCmdConfigImagesPull() *cobra.Command {
kubeadmutil.CheckErr(imagesPull.PullAll())
},
}
AddImagesCommonConfigFlags(cmd.PersistentFlags(), cfg, &cfgPath, &featureGatesString)
AddImagesPullFlags(cmd.PersistentFlags(), cfg)
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString)
AddImagesPullFlags(cmd.PersistentFlags(), externalcfg)
return cmd
}
@@ -456,42 +471,41 @@ func (ip *ImagesPull) PullAll() error {
// NewCmdConfigImagesList returns the "kubeadm config images list" command
func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Command {
cfg := &kubeadmapiv1alpha3.InitConfiguration{}
kubeadmscheme.Scheme.Default(cfg)
externalcfg := &kubeadmapiv1alpha3.InitConfiguration{}
kubeadmscheme.Scheme.Default(externalcfg)
var cfgPath, featureGatesString string
var err error
// This just sets the kubernetes version for unit testing so kubeadm won't try to
// lookup the latest release from the internet.
if mockK8sVersion != nil {
cfg.KubernetesVersion = *mockK8sVersion
externalcfg.KubernetesVersion = *mockK8sVersion
}
cmd := &cobra.Command{
Use: "list",
Short: "Print a list of images kubeadm will use. The configuration file is used in case any images or image repositories are customized.",
Run: func(_ *cobra.Command, _ []string) {
cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
kubeadmutil.CheckErr(err)
imagesList, err := NewImagesList(cfgPath, cfg)
imagesList, err := NewImagesList(cfgPath, externalcfg)
kubeadmutil.CheckErr(err)
kubeadmutil.CheckErr(imagesList.Run(out))
},
}
AddImagesCommonConfigFlags(cmd.PersistentFlags(), cfg, &cfgPath, &featureGatesString)
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString)
return cmd
}
// NewImagesList returns the underlying struct for the "kubeadm config images list" command
func NewImagesList(cfgPath string, cfg *kubeadmapiv1alpha3.InitConfiguration) (*ImagesList, error) {
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
initcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
if err != nil {
return nil, fmt.Errorf("could not convert cfg to an internal cfg: %v", err)
}
return &ImagesList{
cfg: internalcfg,
cfg: initcfg,
}, nil
}
@@ -513,7 +527,7 @@ func (i *ImagesList) Run(out io.Writer) error {
// AddImagesCommonConfigFlags adds the flags that configure kubeadm (and affect the images kubeadm will use)
func AddImagesCommonConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1alpha3.InitConfiguration, cfgPath *string, featureGatesString *string) {
flagSet.StringVar(
&cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion,
&cfg.ClusterConfiguration.KubernetesVersion, "kubernetes-version", cfg.ClusterConfiguration.KubernetesVersion,
`Choose a specific Kubernetes version for the control plane.`,
)
flagSet.StringVar(featureGatesString, "feature-gates", *featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+

View File

@@ -69,7 +69,7 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
},
configContents: []byte(dedent.Dedent(`
apiVersion: kubeadm.k8s.io/v1alpha3
kind: InitConfiguration
kind: ClusterConfiguration
kubernetesVersion: v1.10.1
`)),
},
@@ -81,10 +81,10 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
},
configContents: []byte(dedent.Dedent(`
apiVersion: kubeadm.k8s.io/v1alpha3
kind: InitConfiguration
kind: ClusterConfiguration
kubernetesVersion: v1.11.0
featureGates:
CoreDNS: True
CoreDNS: true
`)),
},
}
@@ -98,13 +98,14 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
defer os.RemoveAll(tmpDir)
configFilePath := filepath.Join(tmpDir, "test-config-file")
err = ioutil.WriteFile(configFilePath, tc.configContents, 0644)
if err != nil {
if err := ioutil.WriteFile(configFilePath, tc.configContents, 0644); err != nil {
t.Fatalf("Failed writing a config file: %v", err)
}
i, err := cmd.NewImagesList(configFilePath, &kubeadmapiv1alpha3.InitConfiguration{
KubernetesVersion: dummyKubernetesVersion,
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
})
if err != nil {
t.Fatalf("Failed getting the kubeadm images command: %v", err)
@@ -137,28 +138,34 @@ func TestConfigImagesListRunWithoutPath(t *testing.T) {
name: "empty config",
expectedImages: defaultNumberOfImages,
cfg: kubeadmapiv1alpha3.InitConfiguration{
KubernetesVersion: dummyKubernetesVersion,
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
},
},
{
name: "external etcd configuration",
cfg: kubeadmapiv1alpha3.InitConfiguration{
Etcd: kubeadmapiv1alpha3.Etcd{
External: &kubeadmapiv1alpha3.ExternalEtcd{
Endpoints: []string{"https://some.etcd.com:2379"},
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
Etcd: kubeadmapiv1alpha3.Etcd{
External: &kubeadmapiv1alpha3.ExternalEtcd{
Endpoints: []string{"https://some.etcd.com:2379"},
},
},
KubernetesVersion: dummyKubernetesVersion,
},
KubernetesVersion: dummyKubernetesVersion,
},
expectedImages: defaultNumberOfImages - 1,
},
{
name: "coredns enabled",
cfg: kubeadmapiv1alpha3.InitConfiguration{
FeatureGates: map[string]bool{
features.CoreDNS: true,
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
FeatureGates: map[string]bool{
features.CoreDNS: true,
},
KubernetesVersion: dummyKubernetesVersion,
},
KubernetesVersion: dummyKubernetesVersion,
},
expectedImages: defaultNumberOfImages,
},
@@ -226,8 +233,9 @@ func TestImagesPull(t *testing.T) {
func TestMigrate(t *testing.T) {
cfg := []byte(dedent.Dedent(`
apiVersion: kubeadm.k8s.io/v1alpha3
kind: InitConfiguration
# This is intentionally testing an old API version and the old kind naming and making sure the output is correct
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.10.0
`))
configFile, cleanup := tempConfig(t, cfg)
@@ -235,13 +243,15 @@ func TestMigrate(t *testing.T) {
var output bytes.Buffer
command := cmd.NewCmdConfigMigrate(&output)
err := command.Flags().Set("old-config", configFile)
if err != nil {
if err := command.Flags().Set("old-config", configFile); err != nil {
t.Fatalf("failed to set old-config flag")
}
newConfigPath := filepath.Join(filepath.Dir(configFile), "new-migrated-config")
if err := command.Flags().Set("new-config", newConfigPath); err != nil {
t.Fatalf("failed to set new-config flag")
}
command.Run(nil, nil)
_, err = config.BytesToInternalConfig(output.Bytes())
if err != nil {
if _, err := config.ConfigFileAndDefaultsToInternalConfig(newConfigPath, &kubeadmapiv1alpha3.InitConfiguration{}); err != nil {
t.Fatalf("Could not read output back into internal type: %v", err)
}
}
@@ -254,8 +264,7 @@ func tempConfig(t *testing.T, config []byte) (string, func()) {
t.Fatalf("Unable to create temporary directory: %v", err)
}
configFilePath := filepath.Join(tmpDir, "test-config-file")
err = ioutil.WriteFile(configFilePath, config, 0644)
if err != nil {
if err := ioutil.WriteFile(configFilePath, config, 0644); err != nil {
os.RemoveAll(tmpDir)
t.Fatalf("Failed writing a config file: %v", err)
}

View File

@@ -152,9 +152,11 @@ func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv
func getSANDescription(certSpec *certsphase.KubeadmCert) string {
//Defaulted config we will use to get SAN certs
defaultConfig := &kubeadmapiv1alpha3.InitConfiguration{
API: kubeadmapiv1alpha3.API{
// GetAPIServerAltNames errors without an AdvertiseAddress; this is as good as any.
AdvertiseAddress: "127.0.0.1",
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
API: kubeadmapiv1alpha3.API{
// GetAPIServerAltNames errors without an AdvertiseAddress; this is as good as any.
AdvertiseAddress: "127.0.0.1",
},
},
}
defaultInternalConfig := &kubeadmapi.InitConfiguration{}

View File

@@ -259,14 +259,16 @@ func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) {
for _, test := range tests {
t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) {
// Create temp folder for the test case
// Create temp folder for the test case
tmpdir := testutil.SetupTempDir(t)
defer os.RemoveAll(tmpdir)
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: tmpdir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: tmpdir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
}
configPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg)

View File

@@ -277,8 +277,10 @@ func TestKubeConfigSubCommandsThatCreateFilesWithConfigFile(t *testing.T) {
// Adds a master configuration file
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
}
cfgPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg)

View File

@@ -179,10 +179,11 @@ func TestRunCreateToken(t *testing.T) {
}
cfg := &kubeadmapiv1alpha3.InitConfiguration{
// KubernetesVersion is not used, but we set this explicitly to avoid
// the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
KubernetesVersion: "v1.10.0",
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
// KubernetesVersion is not used, but we set this explicitly to avoid
// the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
KubernetesVersion: "v1.10.0",
},
BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{
{
Token: bts,

View File

@@ -90,6 +90,7 @@ func NewCmdApply(apf *applyPlanFlags) *cobra.Command {
// If the version is specified in config file, pick up that value.
if flags.cfgPath != "" {
glog.V(1).Infof("fetching configuration from file %s", flags.cfgPath)
// Note that cfg isn't preserved here, it's just an one-off to populate flags.newK8sVersionStr based on --config
cfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(flags.cfgPath, &kubeadmapiv1alpha3.InitConfiguration{})
kubeadmutil.CheckErr(err)
@@ -160,7 +161,7 @@ func RunApply(flags *applyFlags) error {
// Validate requested and validate actual version
glog.V(1).Infof("[upgrade/apply] validating requested and actual version")
if err := configutil.NormalizeKubernetesVersion(upgradeVars.cfg); err != nil {
if err := configutil.NormalizeKubernetesVersion(&upgradeVars.cfg.ClusterConfiguration); err != nil {
return err
}

View File

@@ -154,9 +154,11 @@ func TestSetImplicitFlags(t *testing.T) {
func TestGetPathManagerForUpgrade(t *testing.T) {
haEtcd := &kubeadmapi.InitConfiguration{
Etcd: kubeadmapi.Etcd{
External: &kubeadmapi.ExternalEtcd{
Endpoints: []string{"10.100.0.1:2379", "10.100.0.2:2379", "10.100.0.3:2379"},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
External: &kubeadmapi.ExternalEtcd{
Endpoints: []string{"10.100.0.1:2379", "10.100.0.2:2379", "10.100.0.3:2379"},
},
},
},
}

View File

@@ -95,7 +95,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
// If the user told us to print this information out; do it!
if flags.printConfig {
printConfiguration(cfg, os.Stdout)
printConfiguration(&cfg.ClusterConfiguration, os.Stdout)
}
return &upgradeVariables{
@@ -109,13 +109,13 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
}
// printConfiguration prints the external version of the API to yaml
func printConfiguration(cfg *kubeadmapi.InitConfiguration, w io.Writer) {
func printConfiguration(clustercfg *kubeadmapi.ClusterConfiguration, w io.Writer) {
// Short-circuit if cfg is nil, so we can safely get the value of the pointer below
if cfg == nil {
if clustercfg == nil {
return
}
cfgYaml, err := configutil.MarshalKubeadmConfigObject(cfg)
cfgYaml, err := configutil.MarshalKubeadmConfigObject(clustercfg)
if err == nil {
fmt.Fprintln(w, "[upgrade/config] Configuration used:")

View File

@@ -25,7 +25,7 @@ import (
func TestPrintConfiguration(t *testing.T) {
var tests = []struct {
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
buf *bytes.Buffer
expectedBytes []byte
}{
@@ -34,7 +34,7 @@ func TestPrintConfiguration(t *testing.T) {
expectedBytes: []byte(""),
},
{
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.7.1",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
@@ -57,18 +57,17 @@ func TestPrintConfiguration(t *testing.T) {
dataDir: /some/path
image: ""
imageRepository: ""
kind: InitConfiguration
kind: ClusterConfiguration
kubernetesVersion: v1.7.1
networking:
dnsDomain: ""
podSubnet: ""
serviceSubnet: ""
nodeRegistration: {}
unifiedControlPlaneImage: ""
`),
},
{
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.7.1",
Networking: kubeadmapi.Networking{
ServiceSubnet: "10.96.0.1/12",
@@ -97,13 +96,12 @@ func TestPrintConfiguration(t *testing.T) {
- https://one-etcd-instance:2379
keyFile: ""
imageRepository: ""
kind: InitConfiguration
kind: ClusterConfiguration
kubernetesVersion: v1.7.1
networking:
dnsDomain: ""
podSubnet: ""
serviceSubnet: 10.96.0.1/12
nodeRegistration: {}
unifiedControlPlaneImage: ""
`),
},

View File

@@ -33,7 +33,7 @@ const (
)
// DefaultKubeProxyConfiguration assigns default values for the kube-proxy ComponentConfig
func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration) {
func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
// IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
// and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go. TODO: Remove this requirement when v1alpha2 is removed.
externalproxycfg := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{}
@@ -62,7 +62,7 @@ func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration) {
}
// DefaultKubeletConfiguration assigns default values for the kubelet ComponentConfig
func DefaultKubeletConfiguration(internalcfg *kubeadmapi.InitConfiguration) {
func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) {
// IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go
// and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go. TODO: Remove this requirement when v1alpha2 is removed.
externalkubeletcfg := &kubeletconfigv1beta1.KubeletConfiguration{}

View File

@@ -38,15 +38,15 @@ type Registration struct {
// AddToSchemeFuncs are a set of functions that register APIs to the scheme
AddToSchemeFuncs []AddToSchemeFunc
// DefaulterFunc is a function that based on the internal kubeadm configuration defaults the ComponentConfig struct
DefaulterFunc func(*kubeadmapi.InitConfiguration)
DefaulterFunc func(*kubeadmapi.ClusterConfiguration)
// ValidateFunc is a function that should validate the ComponentConfig type embedded in the internal kubeadm config struct
ValidateFunc func(*kubeadmapi.InitConfiguration, *field.Path) field.ErrorList
ValidateFunc func(*kubeadmapi.ClusterConfiguration, *field.Path) field.ErrorList
// EmptyValue holds a pointer to an empty struct of the internal ComponentConfig type
EmptyValue runtime.Object
// GetFromInternalConfig returns the pointer to the ComponentConfig API object from the internal kubeadm config struct
GetFromInternalConfig func(*kubeadmapi.InitConfiguration) (runtime.Object, bool)
GetFromInternalConfig func(*kubeadmapi.ClusterConfiguration) (runtime.Object, bool)
// SetToInternalConfig sets the pointer to a ComponentConfig API object embedded in the internal kubeadm config struct
SetToInternalConfig func(runtime.Object, *kubeadmapi.InitConfiguration) bool
SetToInternalConfig func(runtime.Object, *kubeadmapi.ClusterConfiguration) bool
}
// Marshal marshals obj to bytes for the current Registration
@@ -89,10 +89,10 @@ var Known Registrations = map[RegistrationKind]Registration{
DefaulterFunc: DefaultKubeProxyConfiguration,
ValidateFunc: ValidateKubeProxyConfiguration,
EmptyValue: &kubeproxyconfig.KubeProxyConfiguration{},
GetFromInternalConfig: func(cfg *kubeadmapi.InitConfiguration) (runtime.Object, bool) {
GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) {
return cfg.ComponentConfigs.KubeProxy, cfg.ComponentConfigs.KubeProxy != nil
},
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.InitConfiguration) bool {
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool {
kubeproxyConfig, ok := obj.(*kubeproxyconfig.KubeProxyConfiguration)
if ok {
cfg.ComponentConfigs.KubeProxy = kubeproxyConfig
@@ -106,10 +106,10 @@ var Known Registrations = map[RegistrationKind]Registration{
DefaulterFunc: DefaultKubeletConfiguration,
ValidateFunc: ValidateKubeletConfiguration,
EmptyValue: &kubeletconfig.KubeletConfiguration{},
GetFromInternalConfig: func(cfg *kubeadmapi.InitConfiguration) (runtime.Object, bool) {
GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) {
return cfg.ComponentConfigs.Kubelet, cfg.ComponentConfigs.Kubelet != nil
},
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.InitConfiguration) bool {
SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool {
kubeletConfig, ok := obj.(*kubeletconfig.KubeletConfiguration)
if ok {
cfg.ComponentConfigs.Kubelet = kubeletConfig
@@ -132,14 +132,14 @@ func (rs *Registrations) AddToScheme(scheme *runtime.Scheme) error {
}
// Default applies to the ComponentConfig defaults to the internal kubeadm API type
func (rs *Registrations) Default(internalcfg *kubeadmapi.InitConfiguration) {
func (rs *Registrations) Default(internalcfg *kubeadmapi.ClusterConfiguration) {
for _, registration := range *rs {
registration.DefaulterFunc(internalcfg)
}
}
// Validate validates the ComponentConfig parts of the internal kubeadm API type
func (rs *Registrations) Validate(internalcfg *kubeadmapi.InitConfiguration) field.ErrorList {
func (rs *Registrations) Validate(internalcfg *kubeadmapi.ClusterConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
for kind, registration := range *rs {
allErrs = append(allErrs, registration.ValidateFunc(internalcfg, field.NewPath(string(kind)))...)

View File

@@ -24,7 +24,7 @@ import (
)
// ValidateKubeProxyConfiguration validates proxy configuration and collects all encountered errors
func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration, _ *field.Path) field.ErrorList {
func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration, _ *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if internalcfg.ComponentConfigs.KubeProxy == nil {
return allErrs
@@ -33,7 +33,7 @@ func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration, _
}
// ValidateKubeletConfiguration validates kubelet configuration and collects all encountered errors
func ValidateKubeletConfiguration(internalcfg *kubeadmapi.InitConfiguration, fldPath *field.Path) field.ErrorList {
func ValidateKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if internalcfg.ComponentConfigs.Kubelet == nil {
return allErrs

View File

@@ -31,12 +31,12 @@ import (
func TestValidateKubeProxyConfiguration(t *testing.T) {
var tests = []struct {
masterConfig *kubeadm.InitConfiguration
msg string
expectErr bool
clusterConfig *kubeadm.ClusterConfiguration
msg string
expectErr bool
}{
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "192.168.59.103",
@@ -67,7 +67,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
expectErr: false,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
// only BindAddress is invalid
@@ -100,7 +100,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
expectErr: true,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
@@ -133,7 +133,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
expectErr: true,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
@@ -166,7 +166,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
expectErr: true,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
@@ -199,7 +199,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
expectErr: true,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
@@ -232,7 +232,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
expectErr: true,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
BindAddress: "10.10.12.11",
@@ -266,7 +266,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
},
}
for i, rt := range tests {
err := ValidateKubeProxyConfiguration(rt.masterConfig, nil).ToAggregate()
err := ValidateKubeProxyConfiguration(rt.clusterConfig, nil).ToAggregate()
if (err != nil) != rt.expectErr {
t.Errorf("%d failed ValidateKubeProxyConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
}
@@ -278,11 +278,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
func TestValidateKubeletConfiguration(t *testing.T) {
var tests = []struct {
masterConfig *kubeadm.InitConfiguration
expectErr bool
clusterConfig *kubeadm.ClusterConfiguration
expectErr bool
}{
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{
CgroupsPerQOS: true,
@@ -313,7 +313,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
expectErr: false,
},
{
masterConfig: &kubeadm.InitConfiguration{
clusterConfig: &kubeadm.ClusterConfiguration{
ComponentConfigs: kubeadm.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{
CgroupsPerQOS: false,
@@ -344,7 +344,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
},
}
for i, rt := range tests {
err := ValidateKubeletConfiguration(rt.masterConfig, nil).ToAggregate()
err := ValidateKubeletConfiguration(rt.clusterConfig, nil).ToAggregate()
if (err != nil) != rt.expectErr {
t.Errorf("%d failed ValidateKubeletConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
}

View File

@@ -187,9 +187,12 @@ const (
AnnotationKubeadmCRISocket = "kubeadm.alpha.kubernetes.io/cri-socket"
// InitConfigurationConfigMap specifies in what ConfigMap in the kube-system namespace the `kubeadm init` configuration should be stored
// TODO: Rename this to ClusterConfigurationConfigMap
InitConfigurationConfigMap = "kubeadm-config"
// InitConfigurationConfigMapKey specifies in what ConfigMap key the master configuration should be stored
// TODO: Rename this to ClusterConfigurationConfigMapKey, and migrate the value to ClusterConfiguration,
// but still support the old MasterConfiguration naming in earlier versions
InitConfigurationConfigMapKey = "InitConfiguration"
// KubeletBaseConfigurationConfigMapPrefix specifies in what ConfigMap in the kube-system namespace the initial remote configuration of kubelet should be stored
@@ -288,6 +291,9 @@ const (
// CoreDNSVersion is the version of CoreDNS to be deployed if it is used
CoreDNSVersion = "1.1.3"
// ClusterConfigurationKind is the string kind value for the ClusterConfiguration struct
ClusterConfigurationKind = "ClusterConfiguration"
// InitConfigurationKind is the string kind value for the InitConfiguration struct
InitConfigurationKind = "InitConfiguration"

View File

@@ -54,31 +54,39 @@ func TestGetKubeControlPlaneImage(t *testing.T) {
{
expected: "override",
cfg: &kubeadmapi.InitConfiguration{
UnifiedControlPlaneImage: "override",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
UnifiedControlPlaneImage: "override",
},
},
},
{
image: constants.KubeAPIServer,
expected: GetGenericArchImage(gcrPrefix, "kube-apiserver", expected),
cfg: &kubeadmapi.InitConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
},
},
},
{
image: constants.KubeControllerManager,
expected: GetGenericArchImage(gcrPrefix, "kube-controller-manager", expected),
cfg: &kubeadmapi.InitConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
},
},
},
{
image: constants.KubeScheduler,
expected: GetGenericArchImage(gcrPrefix, "kube-scheduler", expected),
cfg: &kubeadmapi.InitConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
},
},
},
}
@@ -102,9 +110,11 @@ func TestGetEtcdImage(t *testing.T) {
{
expected: "override",
cfg: &kubeadmapi.InitConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
Image: "override",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
Image: "override",
},
},
},
},
@@ -112,8 +122,10 @@ func TestGetEtcdImage(t *testing.T) {
{
expected: GetGenericArchImage(gcrPrefix, "etcd", constants.DefaultEtcdVersion),
cfg: &kubeadmapi.InitConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
ImageRepository: gcrPrefix,
KubernetesVersion: testversion,
},
},
},
}
@@ -138,22 +150,28 @@ func TestGetAllImages(t *testing.T) {
{
name: "defined CIImageRepository",
cfg: &kubeadmapi.InitConfiguration{
CIImageRepository: "test.repo",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
CIImageRepository: "test.repo",
},
},
expect: "test.repo",
},
{
name: "undefined CIImagerRepository should contain the default image prefix",
cfg: &kubeadmapi.InitConfiguration{
ImageRepository: "real.repo",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
ImageRepository: "real.repo",
},
},
expect: "real.repo",
},
{
name: "test that etcd is returned when it is not external",
cfg: &kubeadmapi.InitConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{},
},
},
},
expect: constants.Etcd,
@@ -161,8 +179,10 @@ func TestGetAllImages(t *testing.T) {
{
name: "CoreDNS image is returned",
cfg: &kubeadmapi.InitConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": true,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": true,
},
},
},
expect: constants.CoreDNS,
@@ -170,8 +190,10 @@ func TestGetAllImages(t *testing.T) {
{
name: "main kube-dns image is returned",
cfg: &kubeadmapi.InitConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": false,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": false,
},
},
},
expect: "k8s-dns-kube-dns",
@@ -179,8 +201,10 @@ func TestGetAllImages(t *testing.T) {
{
name: "kube-dns sidecar image is returned",
cfg: &kubeadmapi.InitConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": false,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": false,
},
},
},
expect: "k8s-dns-sidecar",
@@ -188,8 +212,10 @@ func TestGetAllImages(t *testing.T) {
{
name: "kube-dns dnsmasq-nanny image is returned",
cfg: &kubeadmapi.InitConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": false,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{
"CoreDNS": false,
},
},
},
expect: "k8s-dns-dnsmasq-nanny",

View File

@@ -171,15 +171,17 @@ func TestEnsureProxyAddon(t *testing.T) {
client := clientsetfake.NewSimpleClientset()
// TODO: Consider using a YAML file instead for this that makes it possible to specify YAML documents for the ComponentConfigs
masterConfig := &kubeadmapiv1alpha3.InitConfiguration{
API: kubeadmapiv1alpha3.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 1234,
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
API: kubeadmapiv1alpha3.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 1234,
},
Networking: kubeadmapiv1alpha3.Networking{
PodSubnet: "5.6.7.8/24",
},
ImageRepository: "someRepo",
KubernetesVersion: "v1.10.0",
},
Networking: kubeadmapiv1alpha3.Networking{
PodSubnet: "5.6.7.8/24",
},
ImageRepository: "someRepo",
KubernetesVersion: "v1.10.0",
}
// Simulate an error if necessary

View File

@@ -116,10 +116,12 @@ func TestCreateCertificateChain(t *testing.T) {
defer os.RemoveAll(dir)
ic := &kubeadmapi.InitConfiguration{
CertificatesDir: dir,
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "test-node",
},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
CertificatesDir: dir,
},
}
caCfg := Certificates{

View File

@@ -351,7 +351,9 @@ func TestSharedCertificateExists(t *testing.T) {
defer os.RemoveAll(tmpdir)
cfg := &kubeadmapi.InitConfiguration{
CertificatesDir: tmpdir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
CertificatesDir: tmpdir,
},
}
// created expected keys
@@ -398,10 +400,12 @@ func TestUsingExternalCA(t *testing.T) {
defer os.RemoveAll(dir)
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
CertificatesDir: dir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
CertificatesDir: dir,
}
for _, f := range test.setupFuncs {
@@ -565,11 +569,13 @@ func TestCreateCertificateFilesMethods(t *testing.T) {
defer os.RemoveAll(tmpdir)
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Etcd: kubeadmapi.Etcd{Local: &kubeadmapi.LocalEtcd{}},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Etcd: kubeadmapi.Etcd{Local: &kubeadmapi.LocalEtcd{}},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
CertificatesDir: tmpdir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
CertificatesDir: tmpdir,
}
if test.externalEtcd {

View File

@@ -446,10 +446,12 @@ func TestGetAPIServerAltNames(t *testing.T) {
{
name: "ControlPlaneEndpoint DNS",
cfg: &kubeadmapi.InitConfiguration{
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"},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"},
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"},
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
},
expectedDNSNames: []string{"valid-hostname", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local", "api.k8s.io"},
expectedIPAddresses: []string{"10.96.0.1", "1.2.3.4", "10.1.245.94", "10.1.245.95"},
@@ -457,10 +459,12 @@ func TestGetAPIServerAltNames(t *testing.T) {
{
name: "ControlPlaneEndpoint IP",
cfg: &kubeadmapi.InitConfiguration{
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"},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"},
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"},
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
},
expectedDNSNames: []string{"valid-hostname", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local"},
expectedIPAddresses: []string{"10.96.0.1", "1.2.3.4", "10.1.245.94", "10.1.245.95", "4.5.6.7"},
@@ -507,13 +511,15 @@ func TestGetEtcdAltNames(t *testing.T) {
proxy := "user-etcd-proxy"
proxyIP := "10.10.10.100"
cfg := &kubeadmapi.InitConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ServerCertSANs: []string{
proxy,
proxyIP,
"1.2.3.L",
"invalid,commas,in,DNS",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ServerCertSANs: []string{
proxy,
proxyIP,
"1.2.3.L",
"invalid,commas,in,DNS",
},
},
},
},
@@ -561,18 +567,20 @@ func TestGetEtcdPeerAltNames(t *testing.T) {
proxyIP := "10.10.10.100"
advertiseIP := "1.2.3.4"
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: advertiseIP},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: hostname},
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
PeerCertSANs: []string{
proxy,
proxyIP,
"1.2.3.L",
"invalid,commas,in,DNS",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: advertiseIP},
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
PeerCertSANs: []string{
proxy,
proxyIP,
"1.2.3.L",
"invalid,commas,in,DNS",
},
},
},
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: hostname},
}
altNames, err := GetEtcdPeerAltNames(cfg)

View File

@@ -46,7 +46,9 @@ func TestGetStaticPodSpecs(t *testing.T) {
// Creates a Master Configuration
cfg := &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.9.0",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.9.0",
},
}
// Executes GetStaticPodSpecs
@@ -118,7 +120,9 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) {
// Creates a Master Configuration
cfg := &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.9.0",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.9.0",
},
}
// Execute createStaticPodFunction
@@ -141,12 +145,12 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) {
func TestGetAPIServerCommand(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
expected []string
}{
{
name: "testing defaults",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -183,7 +187,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "ignores the audit policy if the feature gate is not enabled",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "4.3.2.1"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -225,7 +229,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "ipv6 advertise address",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -262,7 +266,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "an external etcd with custom ca, certs and keys",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
FeatureGates: map[string]bool{features.HighAvailability: true},
@@ -309,7 +313,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "an insecure etcd",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
Etcd: kubeadmapi.Etcd{
@@ -348,7 +352,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "auditing and HA are enabled with a custom log max age of 0",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
FeatureGates: map[string]bool{features.HighAvailability: true, features.Auditing: true},
@@ -393,7 +397,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "ensure the DynamicKubelet flag gets passed through",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -432,7 +436,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "test APIServerExtraArgs works as expected",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -480,7 +484,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "authorization-mode extra-args ABAC",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -520,7 +524,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "insecure-port extra-args",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -560,7 +564,7 @@ func TestGetAPIServerCommand(t *testing.T) {
},
{
name: "authorization-mode extra-args Webhook",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "bar"},
CertificatesDir: testCertsDir,
@@ -602,7 +606,11 @@ func TestGetAPIServerCommand(t *testing.T) {
for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) {
actual := getAPIServerCommand(rt.cfg)
// TODO: Make getAPIServerCommand accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
actual := getAPIServerCommand(initcfg)
sort.Strings(actual)
sort.Strings(rt.expected)
if !reflect.DeepEqual(actual, rt.expected) {
@@ -633,12 +641,12 @@ func removeCommon(left, right []string) []string {
func TestGetControllerManagerCommand(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
expected []string
}{
{
name: "custom certs dir",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
CertificatesDir: testCertsDir,
KubernetesVersion: "v1.7.0",
},
@@ -657,7 +665,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
},
{
name: "custom cloudprovider",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"},
CertificatesDir: testCertsDir,
KubernetesVersion: "v1.7.0",
@@ -680,7 +688,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
},
{
name: "custom extra-args",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"},
ControllerManagerExtraArgs: map[string]string{"node-cidr-mask-size": "20"},
CertificatesDir: testCertsDir,
@@ -704,7 +712,7 @@ func TestGetControllerManagerCommand(t *testing.T) {
},
{
name: "custom IPv6 networking",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Networking: kubeadmapi.Networking{PodSubnet: "2001:db8::/64"},
CertificatesDir: testCertsDir,
KubernetesVersion: "v1.7.0",
@@ -728,7 +736,11 @@ func TestGetControllerManagerCommand(t *testing.T) {
}
for _, rt := range tests {
actual := getControllerManagerCommand(rt.cfg, version.MustParseSemantic(rt.cfg.KubernetesVersion))
// TODO: Make getControllerManagerCommand accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
actual := getControllerManagerCommand(initcfg, version.MustParseSemantic(rt.cfg.KubernetesVersion))
sort.Strings(actual)
sort.Strings(rt.expected)
if !reflect.DeepEqual(actual, rt.expected) {
@@ -817,17 +829,16 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) {
tests := []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
caKeyPresent bool
expectedArgFunc func(dir string) []string
}{
{
name: "caKeyPresent-false",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.7.0",
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
},
caKeyPresent: false,
expectedArgFunc: func(tmpdir string) []string {
@@ -847,11 +858,10 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) {
},
{
name: "caKeyPresent true",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.7.0",
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
},
caKeyPresent: true,
expectedArgFunc: func(tmpdir string) []string {
@@ -877,7 +887,12 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) {
defer os.RemoveAll(tmpdir)
test.cfg.CertificatesDir = tmpdir
if err := certs.CreatePKIAssets(test.cfg); err != nil {
// TODO: Make getControllerManagerCommand and CreatePKIAssets accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *test.cfg,
}
if err := certs.CreatePKIAssets(initcfg); err != nil {
t.Errorf("failed creating pki assets: %v", err)
}
@@ -891,7 +906,7 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) {
}
}
actual := getControllerManagerCommand(test.cfg, version.MustParseSemantic(test.cfg.KubernetesVersion))
actual := getControllerManagerCommand(initcfg, version.MustParseSemantic(test.cfg.KubernetesVersion))
expected := test.expectedArgFunc(tmpdir)
sort.Strings(actual)
sort.Strings(expected)
@@ -904,12 +919,12 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) {
func TestGetSchedulerCommand(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
expected []string
}{
{
name: "scheduler defaults",
cfg: &kubeadmapi.InitConfiguration{},
cfg: &kubeadmapi.ClusterConfiguration{},
expected: []string{
"kube-scheduler",
"--address=127.0.0.1",
@@ -920,7 +935,11 @@ func TestGetSchedulerCommand(t *testing.T) {
}
for _, rt := range tests {
actual := getSchedulerCommand(rt.cfg)
// TODO: Make getSchedulerCommand accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
actual := getSchedulerCommand(initcfg)
sort.Strings(actual)
sort.Strings(rt.expected)
if !reflect.DeepEqual(actual, rt.expected) {

View File

@@ -502,13 +502,13 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
ReadOnly: true,
}
var tests = []struct {
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
vol map[string]map[string]v1.Volume
volMount map[string]map[string]v1.VolumeMount
}{
{
// Should ignore files in /etc/ssl/certs
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
CertificatesDir: testCertsDir,
Etcd: kubeadmapi.Etcd{},
FeatureGates: map[string]bool{features.Auditing: true},
@@ -522,7 +522,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
},
{
// Should ignore files in /etc/ssl/certs and in CertificatesDir
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
CertificatesDir: testCertsDir,
Etcd: kubeadmapi.Etcd{
External: &kubeadmapi.ExternalEtcd{
@@ -549,7 +549,11 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
defer func() { caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates"} }()
for _, rt := range tests {
mounts := getHostPathVolumesForTheControlPlane(rt.cfg)
// TODO: Make getHostPathVolumesForTheControlPlane accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
mounts := getHostPathVolumesForTheControlPlane(initcfg)
// Avoid unit test errors when the flexvolume is mounted
if _, ok := mounts.volumes[kubeadmconstants.KubeControllerManager][flexvolumeDirVolumeName]; ok {

View File

@@ -33,11 +33,13 @@ func TestGetEtcdPodSpec(t *testing.T) {
// Creates a Master Configuration
cfg := &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.7.0",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
Image: "",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.7.0",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
Image: "",
},
},
},
}
@@ -59,11 +61,13 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) {
// Creates a Master Configuration
cfg := &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.7.0",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
Image: "k8s.gcr.io/etcd",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.7.0",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
Image: "k8s.gcr.io/etcd",
},
},
},
}
@@ -90,9 +94,11 @@ func TestGetEtcdCommand(t *testing.T) {
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "foo",
},
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
},
},
},
},
@@ -121,12 +127,14 @@ func TestGetEtcdCommand(t *testing.T) {
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "bar",
},
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
ExtraArgs: map[string]string{
"listen-client-urls": "https://10.0.1.10:2379",
"advertise-client-urls": "https://10.0.1.10:2379",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd",
ExtraArgs: map[string]string{
"listen-client-urls": "https://10.0.1.10:2379",
"advertise-client-urls": "https://10.0.1.10:2379",
},
},
},
},
@@ -156,9 +164,11 @@ func TestGetEtcdCommand(t *testing.T) {
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
Name: "wombat",
},
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/etc/foo",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
DataDir: "/etc/foo",
},
},
},
},

View File

@@ -26,14 +26,11 @@ import (
"reflect"
"testing"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs"
@@ -47,7 +44,9 @@ func TestGetKubeConfigSpecsFailsIfCADoesntExists(t *testing.T) {
// Creates a Master Configuration pointing to the pkidir folder
cfg := &kubeadmapi.InitConfiguration{
CertificatesDir: tmpdir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
CertificatesDir: tmpdir,
},
}
// Executes getKubeConfigSpecs
@@ -67,28 +66,38 @@ func TestGetKubeConfigSpecs(t *testing.T) {
// Creates Master Configurations pointing to the pkidir folder
cfgs := []*kubeadmapi.InitConfiguration{
{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
},
{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234},
CertificatesDir: pkidir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
},
{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234},
CertificatesDir: pkidir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
},
{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234},
CertificatesDir: pkidir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
},
{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234},
CertificatesDir: pkidir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
},
}
@@ -307,8 +316,10 @@ func TestCreateKubeconfigFilesAndWrappers(t *testing.T) {
// Creates a Master Configuration pointing to the pkidir folder
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
},
}
// Execs the createKubeConfigFunction
@@ -335,7 +346,9 @@ func TestWriteKubeConfigFailsIfCADoesntExists(t *testing.T) {
// Creates a Master Configuration pointing to the tmpdir folder
cfg := &kubeadmapi.InitConfiguration{
CertificatesDir: tmpdir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
CertificatesDir: tmpdir,
},
}
var tests = []struct {
@@ -380,8 +393,10 @@ func TestWriteKubeConfig(t *testing.T) {
// Creates a Master Configuration pointing to the pkidir folder
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
CertificatesDir: pkidir,
},
}
var tests = []struct {

View File

@@ -33,10 +33,12 @@ func TestCreateConfigMap(t *testing.T) {
nodeName := "fake-node"
client := fake.NewSimpleClientset()
cfg := &kubeadmapi.InitConfiguration{
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodeName},
KubernetesVersion: "v1.11.0",
ComponentConfigs: kubeadmapi.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodeName},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.11.0",
ComponentConfigs: kubeadmapi.ComponentConfigs{
Kubelet: &kubeletconfig.KubeletConfiguration{},
},
},
}

View File

@@ -76,20 +76,19 @@ go_test(
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
"//cmd/kubeadm/app/phases/etcd:go_default_library",
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library",
"//cmd/kubeadm/app/util/etcd:go_default_library",
"//cmd/kubeadm/test:go_default_library",
"//pkg/util/version:go_default_library",
"//staging/src/k8s.io/api/apps/v1:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//vendor/github.com/coreos/etcd/clientv3:go_default_library",
"//vendor/github.com/coreos/etcd/pkg/transport:go_default_library",

View File

@@ -130,8 +130,10 @@ func TestRollbackFiles(t *testing.T) {
func TestShouldBackupAPIServerCertAndKey(t *testing.T) {
cfg := &kubeadmapi.InitConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "test-node"},
}

View File

@@ -28,15 +28,14 @@ import (
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/pkg/transport"
"k8s.io/apimachinery/pkg/runtime"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd"
)
@@ -48,6 +47,12 @@ const (
testConfiguration = `
apiVersion: kubeadm.k8s.io/v1alpha3
kind: InitConfiguration
nodeRegistration:
name: foo
criSocket: ""
---
apiVersion: kubeadm.k8s.io/v1alpha3
kind: ClusterConfiguration
api:
advertiseAddress: 1.2.3.4
bindPort: 6443
@@ -415,7 +420,7 @@ func TestStaticPodControlPlane(t *testing.T) {
}
defer os.RemoveAll(tmpEtcdDataDir)
oldcfg, err := getConfig("v1.9.0", tempCertsDir, tmpEtcdDataDir)
oldcfg, err := getConfig("v1.12.0", tempCertsDir, tmpEtcdDataDir)
if err != nil {
t.Fatalf("couldn't create config: %v", err)
}
@@ -502,15 +507,26 @@ func getAPIServerHash(dir string) (string, error) {
return fmt.Sprintf("%x", sha256.Sum256(fileBytes)), nil
}
// TODO: Make this test function use the rest of the "official" API machinery helper funcs we have inside of kubeadm
func getConfig(version, certsDir, etcdDataDir string) (*kubeadmapi.InitConfiguration, error) {
externalcfg := &kubeadmapiv1alpha3.InitConfiguration{}
internalcfg := &kubeadmapi.InitConfiguration{}
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(fmt.Sprintf(testConfiguration, certsDir, etcdDataDir, version)), externalcfg); err != nil {
return nil, fmt.Errorf("unable to decode config: %v", err)
configBytes := []byte(fmt.Sprintf(testConfiguration, certsDir, etcdDataDir, version))
// Unmarshal the config
cfg, err := configutil.BytesToInternalConfig(configBytes)
if err != nil {
return nil, err
}
kubeadmscheme.Scheme.Convert(externalcfg, internalcfg, nil)
return internalcfg, nil
// Applies dynamic defaults to settings not provided with flags
if err = configutil.SetInitDynamicDefaults(cfg); err != nil {
return nil, err
}
// Validates cfg (flags/configs + defaults + dynamic defaults)
if err = validation.ValidateInitConfiguration(cfg).ToAggregate(); err != nil {
return nil, err
}
return cfg, nil
}
func getTempDir(t *testing.T, name string) (string, func()) {

View File

@@ -45,6 +45,7 @@ go_test(
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",

View File

@@ -43,11 +43,7 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int
fmt.Printf("[uploadconfig] storing the configuration used in ConfigMap %q in the %q Namespace\n", kubeadmconstants.InitConfigurationConfigMap, metav1.NamespaceSystem)
// We don't want to mutate the cfg itself, so create a copy of it using .DeepCopy of it first
cfgToUpload := cfg.DeepCopy()
// Removes sensitive info from the data that will be stored in the config map
cfgToUpload.BootstrapTokens = nil
// Clear the NodeRegistration object.
cfgToUpload.NodeRegistration = kubeadmapi.NodeRegistrationOptions{}
clusterConfigToUpload := cfg.ClusterConfiguration.DeepCopy()
// TODO: Reset the .ComponentConfig struct like this:
// cfgToUpload.ComponentConfigs = kubeadmapi.ComponentConfigs{}
// in order to not upload any other components' config to the kubeadm-config
@@ -56,9 +52,8 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int
// needs to support reading the different components' ConfigMaps first.
// Marshal the object into YAML
cfgYaml, err := configutil.MarshalKubeadmConfigObject(cfgToUpload)
cfgYaml, err := configutil.MarshalKubeadmConfigObject(clusterConfigToUpload)
if err != nil {
fmt.Println("err", err.Error())
return err
}

View File

@@ -17,6 +17,7 @@ limitations under the License.
package uploadconfig
import (
"reflect"
"testing"
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -28,6 +29,7 @@ import (
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
)
func TestUploadConfiguration(t *testing.T) {
@@ -62,21 +64,31 @@ func TestUploadConfiguration(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t2 *testing.T) {
cfg := &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.10.3",
BootstrapTokens: []kubeadmapi.BootstrapToken{
initialcfg := &kubeadmapiv1alpha3.InitConfiguration{
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
API: kubeadmapiv1alpha3.API{
AdvertiseAddress: "1.2.3.4",
},
KubernetesVersion: "v1.10.10",
},
BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{
{
Token: &kubeadmapi.BootstrapTokenString{
Token: &kubeadmapiv1alpha3.BootstrapTokenString{
ID: "abcdef",
Secret: "abcdef0123456789",
},
},
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
NodeRegistration: kubeadmapiv1alpha3.NodeRegistrationOptions{
Name: "node-foo",
CRISocket: "/var/run/custom-cri.sock",
},
}
cfg, err := configutil.ConfigFileAndDefaultsToInternalConfig("", initialcfg)
if err != nil {
t2.Fatalf("UploadConfiguration() error = %v", err)
}
client := clientsetfake.NewSimpleClientset()
if tt.errOnCreate != nil {
client.PrependReactor("create", "configmaps", func(action core.Action) (bool, runtime.Object, error) {
@@ -107,23 +119,13 @@ func TestUploadConfiguration(t *testing.T) {
t2.Fatalf("Fail to find ConfigMap key")
}
decodedCfg := &kubeadmapi.InitConfiguration{}
decodedCfg := &kubeadmapi.ClusterConfiguration{}
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(configData), decodedCfg); err != nil {
t2.Fatalf("unable to decode config from bytes: %v", err)
}
if decodedCfg.KubernetesVersion != cfg.KubernetesVersion {
t2.Errorf("Decoded value doesn't match, decoded = %#v, expected = %#v", decodedCfg.KubernetesVersion, cfg.KubernetesVersion)
}
// If the decoded cfg has a BootstrapTokens array, verify the sensitive information we had isn't still there.
if len(decodedCfg.BootstrapTokens) > 0 && decodedCfg.BootstrapTokens[0].Token != nil && decodedCfg.BootstrapTokens[0].Token.String() == cfg.BootstrapTokens[0].Token.String() {
t2.Errorf("Decoded value contains .BootstrapTokens (sensitive info), decoded = %#v, expected = empty", decodedCfg.BootstrapTokens)
}
// Make sure no information from NodeRegistrationOptions was uploaded.
if decodedCfg.NodeRegistration.Name == cfg.NodeRegistration.Name || decodedCfg.NodeRegistration.CRISocket != kubeadmapiv1alpha3.DefaultCRISocket {
t2.Errorf("Decoded value contains .NodeRegistration (node-specific info shouldn't be uploaded), decoded = %#v, expected = empty", decodedCfg.NodeRegistration)
if !reflect.DeepEqual(decodedCfg, &cfg.ClusterConfiguration) {
t2.Errorf("the initial and decoded ClusterConfiguration didn't match")
}
}
})

View File

@@ -186,46 +186,49 @@ func (pfct preflightCheckTest) Check() (warning, errors []error) {
func TestRunInitMasterChecks(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
expected bool
}{
{name: "Test valid advertised address",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "foo"},
},
expected: false,
},
{
name: "Test CA file exists if specfied",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{External: &kubeadmapi.ExternalEtcd{CAFile: "/foo"}},
},
expected: false,
},
{
name: "Test Cert file exists if specfied",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{External: &kubeadmapi.ExternalEtcd{CertFile: "/foo"}},
},
expected: false,
},
{
name: "Test Key file exists if specfied",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{External: &kubeadmapi.ExternalEtcd{CertFile: "/foo"}},
},
expected: false,
},
{
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{AdvertiseAddress: "2001:1234::1:15"},
},
expected: false,
},
}
for _, rt := range tests {
actual := RunInitMasterChecks(exec.New(), rt.cfg, sets.NewString())
// TODO: Make RunInitMasterChecks accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
actual := RunInitMasterChecks(exec.New(), initcfg, sets.NewString())
if (actual == nil) != rt.expected {
t.Errorf(
"failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t\n\t error: %v",

View File

@@ -29,6 +29,7 @@ import (
)
// FetchConfigFromFileOrCluster fetches configuration required for upgrading your cluster from a file (which has precedence) or a ConfigMap in the cluster
// TODO: This func should be renamed FetchClusterConfigFromFileOrCluster, and return a ClusterConfiguration instead of an InitConfiguration
func FetchConfigFromFileOrCluster(client clientset.Interface, w io.Writer, logPrefix, cfgPath string) (*kubeadmapi.InitConfiguration, error) {
// Load the configuration from a file or the cluster
configBytes, err := loadConfigurationBytes(client, w, logPrefix, cfgPath)
@@ -36,8 +37,17 @@ func FetchConfigFromFileOrCluster(client clientset.Interface, w io.Writer, logPr
return nil, err
}
// Take the versioned configuration populated from the file or ConfigMap, convert it to internal, default and validate
return BytesToInternalConfig(configBytes)
// Unmarshal the versioned configuration populated from the file or ConfigMap, convert it to the internal API types, then default and validate
initcfg, err := BytesToInternalConfig(configBytes)
if err != nil {
return nil, err
}
// In this function we're only interested in the ClusterConfiguration part.
// TODO: As described above, the return value of this func actually should be a ClusterConfiguration
if err := SetClusterDynamicDefaults(&initcfg.ClusterConfiguration); err != nil {
return nil, err
}
return initcfg, err
}
// loadConfigurationBytes loads the configuration byte slice from either a file or the cluster ConfigMap
@@ -50,6 +60,8 @@ func loadConfigurationBytes(client clientset.Interface, w io.Writer, logPrefix,
fmt.Fprintf(w, "[%s] Reading configuration from the cluster...\n", logPrefix)
// TODO: This code should support reading the MasterConfiguration key as well for backwards-compat
// Also, the key really should be ClusterConfiguration...
configMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(constants.InitConfigurationConfigMap, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
// Return the apierror directly so the caller of this function can know what type of error occurred and act based on that

View File

@@ -17,7 +17,6 @@ limitations under the License.
package config
import (
"fmt"
"os"
"strings"
"testing"
@@ -42,22 +41,24 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) {
{
name: "fetch valid config from configMap",
testCfg: &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.10.3",
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.10.3",
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
},
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15/16",
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15/16",
},
CertificatesDir: "/some/other/cert/dir",
BootstrapTokens: []kubeadm.BootstrapToken{
{
Token: &kubeadm.BootstrapTokenString{
@@ -75,22 +76,24 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) {
{
name: "fetch invalid config from configMap",
testCfg: &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.10.3",
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.10.3",
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
},
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15", // wrong
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15",
},
CertificatesDir: "/some/other/cert/dir",
BootstrapTokens: []kubeadm.BootstrapToken{
{
Token: &kubeadm.BootstrapTokenString{
@@ -108,24 +111,26 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) {
},
{
name: "fetch valid config from cfgPath",
cfgPath: "testdata/conversion/master/v1alpha2.yaml",
cfgPath: "testdata/conversion/master/v1alpha3.yaml",
testCfg: &kubeadmapi.InitConfiguration{
KubernetesVersion: "v1.10.3",
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
KubernetesVersion: "v1.10.3",
API: kubeadm.API{
AdvertiseAddress: "1.2.3.4",
BindPort: 6443,
},
Etcd: kubeadm.Etcd{
Local: &kubeadm.LocalEtcd{
DataDir: "/some/path",
},
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15",
},
CertificatesDir: "/some/other/cert/dir",
},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
PodSubnet: "10.0.1.15",
},
CertificatesDir: "/some/other/cert/dir",
BootstrapTokens: []kubeadm.BootstrapToken{
{
Token: &kubeadm.BootstrapTokenString{
@@ -147,7 +152,7 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) {
},
{
name: "fetch config from not exist cfgPath",
cfgPath: "testdata231/defaulting/master/defaulted.yaml",
cfgPath: "doesnotexist.yaml",
expectErr: "no such file or directory",
},
{
@@ -160,18 +165,17 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
client := clientsetfake.NewSimpleClientset()
if tt.testCfg != nil {
err := createConfigMapWithCfg(tt.testCfg, client)
if err != nil {
if err := createConfigMapWithCfg(tt.testCfg, client); err != nil {
t.Errorf("UploadConfiguration failed err: %v", err)
}
}
_, err := FetchConfigFromFileOrCluster(client, os.Stdout, "upgrade/config", tt.cfgPath)
if len(tt.expectErr) == 0 {
if err != nil {
if err != nil {
if len(tt.expectErr) == 0 {
t.Fatalf("expected no err, but got err: %v", err)
} else if !strings.Contains(err.Error(), tt.expectErr) {
t.Errorf("expected contain err: %v, but got err: %v", tt.expectErr, err)
}
} else if !strings.Contains(err.Error(), tt.expectErr) {
t.Errorf("expected contain err: %v, but got err: %v", tt.expectErr, err)
}
})
}
@@ -181,11 +185,10 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) {
func createConfigMapWithCfg(cfgToCreate *kubeadmapi.InitConfiguration, client clientset.Interface) error {
cfgYaml, err := MarshalKubeadmConfigObject(cfgToCreate)
if err != nil {
fmt.Println("err", err.Error())
return err
}
err = apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{
return apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: kubeadmconstants.InitConfigurationConfigMap,
Namespace: metav1.NamespaceSystem,
@@ -194,8 +197,4 @@ func createConfigMapWithCfg(cfgToCreate *kubeadmapi.InitConfiguration, client cl
kubeadmconstants.InitConfigurationConfigMapKey: string(cfgYaml),
},
})
if err != nil {
return err
}
return nil
}

View File

@@ -54,11 +54,13 @@ func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error)
return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks)
}
// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration, some extra logic is run
// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration or ClusterConfiguration, some extra logic is run
func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, error) {
switch internalcfg := obj.(type) {
case *kubeadmapi.InitConfiguration:
return MarshalInitConfigurationToBytes(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion)
case *kubeadmapi.ClusterConfiguration:
return MarshalClusterConfigurationToBytes(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion)
default:
return kubeadmutil.MarshalToYamlForCodecs(obj, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs)
}
@@ -108,7 +110,7 @@ func DetectUnsupportedVersion(b []byte) error {
// NormalizeKubernetesVersion resolves version labels, sets alternative
// image registry if requested for CI builds, and validates minimal
// version that kubeadm SetInitDynamicDefaultssupports.
func NormalizeKubernetesVersion(cfg *kubeadmapi.InitConfiguration) error {
func NormalizeKubernetesVersion(cfg *kubeadmapi.ClusterConfiguration) error {
// Requested version is automatic CI build, thus use KubernetesCI Image Repository for core images
if kubeadmutil.KubernetesIsCIVersion(cfg.KubernetesVersion) {
cfg.CIImageRepository = constants.DefaultCIImageRepository

View File

@@ -204,7 +204,9 @@ func TestLowercaseSANs(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cfg := &kubeadmapiv1alpha3.InitConfiguration{
APIServerCertSANs: test.in,
ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{
APIServerCertSANs: test.in,
},
}
LowercaseSANs(cfg.APIServerCertSANs)

View File

@@ -43,7 +43,44 @@ import (
// SetInitDynamicDefaults checks and sets configuration values for the InitConfiguration object
func SetInitDynamicDefaults(cfg *kubeadmapi.InitConfiguration) error {
// Populate the .Token field with a random value if unset
// We do this at this layer, and not the API defaulting layer
// because of possible security concerns, and more practically
// because we can't return errors in the API object defaulting
// process but here we can.
for i, bt := range cfg.BootstrapTokens {
if bt.Token != nil && len(bt.Token.String()) > 0 {
continue
}
tokenStr, err := bootstraputil.GenerateBootstrapToken()
if err != nil {
return fmt.Errorf("couldn't generate random token: %v", err)
}
token, err := kubeadmapi.NewBootstrapTokenString(tokenStr)
if err != nil {
return err
}
cfg.BootstrapTokens[i].Token = token
}
var err error
cfg.NodeRegistration.Name, err = nodeutil.GetHostname(cfg.NodeRegistration.Name)
if err != nil {
return err
}
// Only if the slice is nil, we should append the master taint. This allows the user to specify an empty slice for no default master taint
if cfg.NodeRegistration.Taints == nil {
cfg.NodeRegistration.Taints = []v1.Taint{kubeadmconstants.MasterTaint}
}
// Do all the defaulting for the nested ClusterConfiguration as well
return SetClusterDynamicDefaults(&cfg.ClusterConfiguration)
}
// SetClusterDynamicDefaults checks and sets configuration values for the InitConfiguration object
func SetClusterDynamicDefaults(cfg *kubeadmapi.ClusterConfiguration) error {
// Default all the embedded ComponentConfig structs
componentconfigs.Known.Default(cfg)
@@ -72,38 +109,6 @@ func SetInitDynamicDefaults(cfg *kubeadmapi.InitConfiguration) error {
// Downcase SANs. Some domain names (like ELBs) have capitals in them.
LowercaseSANs(cfg.APIServerCertSANs)
// Populate the .Token field with a random value if unset
// We do this at this layer, and not the API defaulting layer
// because of possible security concerns, and more practically
// because we can't return errors in the API object defaulting
// process but here we can.
for i, bt := range cfg.BootstrapTokens {
if bt.Token != nil && len(bt.Token.String()) > 0 {
continue
}
tokenStr, err := bootstraputil.GenerateBootstrapToken()
if err != nil {
return fmt.Errorf("couldn't generate random token: %v", err)
}
token, err := kubeadmapi.NewBootstrapTokenString(tokenStr)
if err != nil {
return err
}
cfg.BootstrapTokens[i].Token = token
}
cfg.NodeRegistration.Name, err = nodeutil.GetHostname(cfg.NodeRegistration.Name)
if err != nil {
return err
}
// Only if the slice is nil, we should append the master taint. This allows the user to specify an empty slice for no default master taint
if cfg.NodeRegistration.Taints == nil {
cfg.NodeRegistration.Taints = []v1.Taint{kubeadmconstants.MasterTaint}
}
return nil
}
@@ -124,24 +129,35 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *
if err != nil {
return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err)
}
return BytesToInternalConfig(b)
internalcfg, err = BytesToInternalConfig(b)
if err != nil {
return nil, err
}
} else {
// Takes passed flags into account; the defaulting is executed once again enforcing assignment of
// static default values to cfg only for values not provided with flags
kubeadmscheme.Scheme.Default(defaultversionedcfg)
kubeadmscheme.Scheme.Convert(defaultversionedcfg, internalcfg, nil)
}
// Takes passed flags into account; the defaulting is executed once again enforcing assignment of
// static default values to cfg only for values not provided with flags
kubeadmscheme.Scheme.Default(defaultversionedcfg)
kubeadmscheme.Scheme.Convert(defaultversionedcfg, internalcfg, nil)
return defaultAndValidate(internalcfg)
// Applies dynamic defaults to settings not provided with flags
if err := SetInitDynamicDefaults(internalcfg); err != nil {
return nil, err
}
// Validates cfg (flags/configs + defaults + dynamic defaults)
if err := validation.ValidateInitConfiguration(internalcfg).ToAggregate(); err != nil {
return nil, err
}
return internalcfg, nil
}
// BytesToInternalConfig converts a byte slice to an internal, defaulted and validated configuration object.
// The byte slice may contain one or many different YAML documents. These YAML documents are parsed one-by-one
// and well-known ComponentConfig GroupVersionKinds are stored inside of the internal InitConfiguration struct
func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) {
internalcfg := &kubeadmapi.InitConfiguration{}
decodedObjs := map[componentconfigs.RegistrationKind]runtime.Object{}
masterConfigFound := false
var initcfg *kubeadmapi.InitConfiguration
var clustercfg *kubeadmapi.ClusterConfiguration
decodedComponentConfigObjects := map[componentconfigs.RegistrationKind]runtime.Object{}
if err := DetectUnsupportedVersion(b); err != nil {
return nil, err
@@ -162,30 +178,57 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) {
if err != nil {
return nil, err
}
decodedObjs[regKind] = obj
decodedComponentConfigObjects[regKind] = obj
continue
}
if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvk) {
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, internalcfg); err != nil {
// Set initcfg to an empty struct value the deserializer will populate
initcfg = &kubeadmapi.InitConfiguration{}
// Decode the bytes into the internal struct. Under the hood, the bytes will be unmarshalled into the
// right external version, defaulted, and converted into the internal version.
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, initcfg); err != nil {
return nil, err
}
continue
}
if kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvk) {
// Set clustercfg to an empty struct value the deserializer will populate
clustercfg = &kubeadmapi.ClusterConfiguration{}
// Decode the bytes into the internal struct. Under the hood, the bytes will be unmarshalled into the
// right external version, defaulted, and converted into the internal version.
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, clustercfg); err != nil {
return nil, err
}
masterConfigFound = true
continue
}
fmt.Printf("[config] WARNING: Ignored YAML document with GroupVersionKind %v\n", gvk)
}
// Just as an extra safety check, don't proceed if a InitConfiguration object wasn't found
if !masterConfigFound {
return nil, fmt.Errorf("no InitConfiguration kind was found in the YAML file")
// Enforce that InitConfiguration and/or ClusterConfiguration has to exist among the YAML documents
if initcfg == nil && clustercfg == nil {
return nil, fmt.Errorf("no InitConfiguration or ClusterConfiguration kind was found in the YAML file")
}
// Save the loaded ComponentConfig objects in the internalcfg object
for kind, obj := range decodedObjs {
// If InitConfiguration wasn't given, default it by creating an external struct instance, default it and convert into the internal type
if initcfg == nil {
extinitcfg := &kubeadmapiv1alpha3.InitConfiguration{}
kubeadmscheme.Scheme.Default(extinitcfg)
// Set initcfg to an empty struct value the deserializer will populate
initcfg = &kubeadmapi.InitConfiguration{}
kubeadmscheme.Scheme.Convert(extinitcfg, initcfg, nil)
}
// If ClusterConfiguration was given, populate it in the InitConfiguration struct
if clustercfg != nil {
initcfg.ClusterConfiguration = *clustercfg
}
// Save the loaded ComponentConfig objects in the initcfg object
for kind, obj := range decodedComponentConfigObjects {
registration, found := componentconfigs.Known[kind]
if found {
if ok := registration.SetToInternalConfig(obj, internalcfg); !ok {
if ok := registration.SetToInternalConfig(obj, &initcfg.ClusterConfiguration); !ok {
return nil, fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind))
}
} else {
@@ -193,26 +236,12 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) {
fmt.Printf("[config] WARNING: Decoded a kind that couldn't be saved to the internal configuration: %q\n", string(kind))
}
}
return defaultAndValidate(internalcfg)
return initcfg, nil
}
func defaultAndValidate(cfg *kubeadmapi.InitConfiguration) (*kubeadmapi.InitConfiguration, error) {
// Applies dynamic defaults to settings not provided with flags
if err := SetInitDynamicDefaults(cfg); err != nil {
return nil, err
}
// Validates cfg (flags/configs + defaults + dynamic defaults)
if err := validation.ValidateInitConfiguration(cfg).ToAggregate(); err != nil {
return nil, err
}
return cfg, nil
}
func defaultedInternalConfig() *kubeadmapi.InitConfiguration {
externalcfg := &kubeadmapiv1alpha3.InitConfiguration{}
internalcfg := &kubeadmapi.InitConfiguration{}
func defaultedInternalConfig() *kubeadmapi.ClusterConfiguration {
externalcfg := &kubeadmapiv1alpha3.ClusterConfiguration{}
internalcfg := &kubeadmapi.ClusterConfiguration{}
kubeadmscheme.Scheme.Default(externalcfg)
kubeadmscheme.Scheme.Convert(externalcfg, internalcfg, nil)
@@ -223,41 +252,57 @@ func defaultedInternalConfig() *kubeadmapi.InitConfiguration {
}
// MarshalInitConfigurationToBytes marshals the internal InitConfiguration object to bytes. It writes the embedded
// ComponentConfiguration objects out as separate YAML documents
// ClusterConfiguration object with ComponentConfigs out as separate YAML documents
func MarshalInitConfigurationToBytes(cfg *kubeadmapi.InitConfiguration, gv schema.GroupVersion) ([]byte, error) {
masterbytes, err := kubeadmutil.MarshalToYamlForCodecs(cfg, gv, kubeadmscheme.Codecs)
initbytes, err := kubeadmutil.MarshalToYamlForCodecs(cfg, gv, kubeadmscheme.Codecs)
if err != nil {
return []byte{}, err
}
allFiles := [][]byte{masterbytes}
componentConfigContent := map[string][]byte{}
allFiles := [][]byte{initbytes}
// If the specified groupversion is targeting the internal type, don't print the extra componentconfig YAML documents
// Exception: If the specified groupversion is targeting the internal type, don't print embedded ClusterConfiguration contents
// This is mostly used for unit testing. In a real scenario the internal version of the API is never marshalled as-is.
if gv.Version != runtime.APIVersionInternal {
clusterbytes, err := MarshalClusterConfigurationToBytes(&cfg.ClusterConfiguration, gv)
if err != nil {
return []byte{}, err
}
allFiles = append(allFiles, clusterbytes)
}
return bytes.Join(allFiles, []byte(kubeadmconstants.YAMLDocumentSeparator)), nil
}
defaultedcfg := defaultedInternalConfig()
// MarshalClusterConfigurationToBytes marshals the internal ClusterConfiguration object to bytes. It writes the embedded
// ComponentConfiguration objects out as separate YAML documents
func MarshalClusterConfigurationToBytes(clustercfg *kubeadmapi.ClusterConfiguration, gv schema.GroupVersion) ([]byte, error) {
clusterbytes, err := kubeadmutil.MarshalToYamlForCodecs(clustercfg, gv, kubeadmscheme.Codecs)
if err != nil {
return []byte{}, err
}
allFiles := [][]byte{clusterbytes}
componentConfigContent := map[string][]byte{}
defaultedcfg := defaultedInternalConfig()
for kind, registration := range componentconfigs.Known {
// If the ComponentConfig struct for the current registration is nil, skip it when marshalling
realobj, ok := registration.GetFromInternalConfig(cfg)
if !ok {
continue
}
defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg)
// Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference
if !ok {
return []byte{}, fmt.Errorf("couldn't create a default componentconfig object")
}
// If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it
if !reflect.DeepEqual(realobj, defaultedobj) {
contentBytes, err := registration.Marshal(realobj)
if err != nil {
return []byte{}, err
}
componentConfigContent[string(kind)] = contentBytes
for kind, registration := range componentconfigs.Known {
// If the ComponentConfig struct for the current registration is nil, skip it when marshalling
realobj, ok := registration.GetFromInternalConfig(clustercfg)
if !ok {
continue
}
defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg)
// Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference
if !ok {
return []byte{}, fmt.Errorf("couldn't create a default componentconfig object")
}
// If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it
if !reflect.DeepEqual(realobj, defaultedobj) {
contentBytes, err := registration.Marshal(realobj)
if err != nil {
return []byte{}, err
}
componentConfigContent[string(kind)] = contentBytes
}
}

View File

@@ -1,3 +1,20 @@
apiVersion: kubeadm.k8s.io/v1alpha3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: s73ybu.6tw6wnqgp5z0wb77
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: master-1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
api:
advertiseAddress: 192.168.2.2
bindPort: 6443
@@ -9,14 +26,6 @@ auditPolicy:
logDir: /var/log/kubernetes/audit
logMaxAge: 2
path: ""
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: s73ybu.6tw6wnqgp5z0wb77
ttl: 24h0m0s
usages:
- signing
- authentication
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
etcd:
@@ -24,18 +33,12 @@ etcd:
dataDir: /var/lib/etcd
image: ""
imageRepository: k8s.gcr.io
kind: InitConfiguration
kind: ClusterConfiguration
kubernetesVersion: v1.10.2
networking:
dnsDomain: cluster.local
podSubnet: ""
serviceSubnet: 10.96.0.0/12
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: master-1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
unifiedControlPlaneImage: ""
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1

View File

@@ -1,3 +1,20 @@
apiVersion: kubeadm.k8s.io/v1alpha3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: s73ybu.6tw6wnqgp5z0wb77
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
nodeRegistration:
criSocket: /var/run/criruntime.sock
name: master-1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
api:
advertiseAddress: 192.168.2.2
bindPort: 6443
@@ -7,14 +24,6 @@ auditPolicy:
logDir: /var/log/kubernetes/audit
logMaxAge: 2
path: ""
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: s73ybu.6tw6wnqgp5z0wb77
ttl: 24h0m0s
usages:
- signing
- authentication
certificatesDir: /var/lib/kubernetes/pki
clusterName: kubernetes
etcd:
@@ -22,18 +31,12 @@ etcd:
dataDir: /var/lib/etcd
image: ""
imageRepository: my-company.com
kind: InitConfiguration
kind: ClusterConfiguration
kubernetesVersion: v1.10.2
networking:
dnsDomain: cluster.global
podSubnet: 10.148.0.0/16
serviceSubnet: 10.196.0.0/12
nodeRegistration:
criSocket: /var/run/criruntime.sock
name: master-1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
unifiedControlPlaneImage: ""
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1

View File

@@ -147,6 +147,11 @@ func GroupVersionKindsHasKind(gvks []schema.GroupVersionKind, kind string) bool
return false
}
// GroupVersionKindsHasClusterConfiguration returns whether the following gvk slice contains a ClusterConfiguration object
func GroupVersionKindsHasClusterConfiguration(gvks ...schema.GroupVersionKind) bool {
return GroupVersionKindsHasKind(gvks, constants.ClusterConfigurationKind)
}
// GroupVersionKindsHasInitConfiguration returns whether the following gvk slice contains a InitConfiguration object
func GroupVersionKindsHasInitConfiguration(gvks ...schema.GroupVersionKind) bool {
// Finding a MasterConfiguration kind is also okay, as it will decode and convert into an InitConfiguration struct eventually

View File

@@ -111,26 +111,21 @@ func TestMarshalUnmarshalYaml(t *testing.T) {
func TestMarshalUnmarshalToYamlForCodecs(t *testing.T) {
cfg := &kubeadmapiv1alpha3.InitConfiguration{
TypeMeta: metav1.TypeMeta{
Kind: "InitConfiguration",
Kind: constants.InitConfigurationKind,
APIVersion: kubeadmapiv1alpha3.SchemeGroupVersion.String(),
},
API: kubeadmapiv1alpha3.API{
AdvertiseAddress: "10.100.0.1",
BindPort: 4332,
},
NodeRegistration: kubeadmapiv1alpha3.NodeRegistrationOptions{
Name: "testNode",
CRISocket: "/var/run/cri.sock",
},
Networking: kubeadmapiv1alpha3.Networking{
ServiceSubnet: "10.100.0.0/24",
PodSubnet: "10.100.1.0/24",
},
BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{
{
Token: &kubeadmapiv1alpha3.BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"},
},
},
// NOTE: Using MarshalToYamlForCodecs and UnmarshalFromYamlForCodecs for ClusterConfiguration fields here won't work
// by design. This is because we have a `json:"-"` annotation in order to avoid struct duplication. See the comment
// at the kubeadmapiv1alpha3.InitConfiguration definition.
}
kubeadmapiv1alpha3.SetDefaults_InitConfiguration(cfg)

View File

@@ -46,7 +46,7 @@ func TestComponentResources(t *testing.T) {
func TestComponentProbe(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
component string
port int
path string
@@ -55,7 +55,7 @@ func TestComponentProbe(t *testing.T) {
}{
{
name: "default apiserver advertise address with http",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{
AdvertiseAddress: "",
},
@@ -68,7 +68,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "default apiserver advertise address with http",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{
AdvertiseAddress: "1.2.3.4",
},
@@ -84,7 +84,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "default apiserver advertise address with https",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{
AdvertiseAddress: "",
},
@@ -97,7 +97,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "valid ipv4 apiserver advertise address with http",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{
AdvertiseAddress: "1.2.3.4",
},
@@ -110,7 +110,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "valid ipv6 apiserver advertise address with http",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
API: kubeadmapi.API{
AdvertiseAddress: "2001:db8::1",
},
@@ -123,7 +123,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "valid IPv4 controller-manager probe",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
ControllerManagerExtraArgs: map[string]string{"address": "1.2.3.4"},
},
component: kubeadmconstants.KubeControllerManager,
@@ -134,7 +134,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "valid IPv6 controller-manager probe",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
ControllerManagerExtraArgs: map[string]string{"address": "2001:db8::1"},
},
component: kubeadmconstants.KubeControllerManager,
@@ -145,7 +145,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "valid IPv4 scheduler probe",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
SchedulerExtraArgs: map[string]string{"address": "1.2.3.4"},
},
component: kubeadmconstants.KubeScheduler,
@@ -156,7 +156,7 @@ func TestComponentProbe(t *testing.T) {
},
{
name: "valid IPv6 scheduler probe",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
SchedulerExtraArgs: map[string]string{"address": "2001:db8::1"},
},
component: kubeadmconstants.KubeScheduler,
@@ -167,7 +167,11 @@ func TestComponentProbe(t *testing.T) {
},
}
for _, rt := range tests {
actual := ComponentProbe(rt.cfg, rt.component, rt.port, rt.path, rt.scheme)
// TODO: Make ComponentProbe accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
actual := ComponentProbe(initcfg, rt.component, rt.port, rt.path, rt.scheme)
if actual.Handler.HTTPGet.Host != rt.expected {
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
rt.name, rt.expected,
@@ -194,7 +198,7 @@ func TestComponentProbe(t *testing.T) {
func TestEtcdProbe(t *testing.T) {
var tests = []struct {
name string
cfg *kubeadmapi.InitConfiguration
cfg *kubeadmapi.ClusterConfiguration
component string
port int
certsDir string
@@ -205,7 +209,7 @@ func TestEtcdProbe(t *testing.T) {
}{
{
name: "valid etcd probe using listen-client-urls IPv4 addresses",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -223,7 +227,7 @@ func TestEtcdProbe(t *testing.T) {
},
{
name: "valid etcd probe using listen-client-urls unspecified IPv6 address",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -241,7 +245,7 @@ func TestEtcdProbe(t *testing.T) {
},
{
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 2",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -259,7 +263,7 @@ func TestEtcdProbe(t *testing.T) {
},
{
name: "valid etcd probe using listen-client-urls unspecified IPv6 address 3",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -277,7 +281,7 @@ func TestEtcdProbe(t *testing.T) {
},
{
name: "valid etcd probe using listen-client-urls unspecified IPv4 address",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -295,7 +299,7 @@ func TestEtcdProbe(t *testing.T) {
},
{
name: "valid etcd probe using listen-client-urls IPv6 addresses",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -313,7 +317,7 @@ func TestEtcdProbe(t *testing.T) {
},
{
name: "valid IPv4 etcd probe using hostname for listen-client-urls",
cfg: &kubeadmapi.InitConfiguration{
cfg: &kubeadmapi.ClusterConfiguration{
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ExtraArgs: map[string]string{
@@ -331,7 +335,11 @@ func TestEtcdProbe(t *testing.T) {
},
}
for _, rt := range tests {
actual := EtcdProbe(rt.cfg, rt.component, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
// TODO: Make EtcdProbe accept a ClusterConfiguration object instead of InitConfiguration
initcfg := &kubeadmapi.InitConfiguration{
ClusterConfiguration: *rt.cfg,
}
actual := EtcdProbe(initcfg, rt.component, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key)
if actual.Handler.Exec.Command[2] != rt.expected {
t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s",
rt.name, rt.expected,

View File

@@ -55,12 +55,15 @@ func SetupInitConfigurationFile(t *testing.T, tmpdir string, cfg *kubeadmapi.Ini
cfgTemplate := template.Must(template.New("init").Parse(dedent.Dedent(`
apiVersion: kubeadm.k8s.io/v1alpha3
kind: InitConfiguration
nodeRegistration:
name: {{.NodeRegistration.Name}}
---
apiVersion: kubeadm.k8s.io/v1alpha3
kind: ClusterConfiguration
certificatesDir: {{.CertificatesDir}}
api:
advertiseAddress: {{.API.AdvertiseAddress}}
bindPort: {{.API.BindPort}}
nodeRegistration:
name: {{.NodeRegistration.Name}}
kubernetesVersion: v1.10.0
`)))