kubeadm: Remove ClusterConfiguration from InitConfiguration in v1beta2

Ever since v1alpha3, InitConfiguration is containing ClusterConfiguration
embedded in it. This was done to mimic the internal InitConfiguration, which in
turn is used throughout the kubeadm code base as if it is the old
MasterConfiguration of v1alpha2.

This, however, is confusing to users who vendor in kubeadm as the embedded
ClusterConfiguration inside InitConfiguration is not marshalled to YAML.
For this to happen, special care must be taken for the ClusterConfiguration
field to marshalled separately.

Thus, to make things smooth for users and to reduce third party exposure to
technical debt, this change removes ClusterConfiguration embedding from
InitConfiguration.

Signed-off-by: Rostislav M. Georgiev <rostislavg@vmware.com>
This commit is contained in:
Rostislav M. Georgiev 2019-05-08 12:02:32 +03:00
parent 306b6f330d
commit 5671ea9cf1
20 changed files with 211 additions and 182 deletions

View File

@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"bootstraptokenstring.go",
"conversion.go",
"defaults.go",
"defaults_unix.go",
"defaults_windows.go",

View File

@ -0,0 +1,38 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta2
import (
conversion "k8s.io/apimachinery/pkg/conversion"
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
)
func Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error {
return autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in, out, s)
}
func Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
err := autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s)
if err != nil {
return err
}
// Keep the fuzzer test happy by setting out.ClusterConfiguration to defaults
clusterCfg := &ClusterConfiguration{}
SetDefaults_ClusterConfiguration(clusterCfg)
return Convert_v1beta2_ClusterConfiguration_To_kubeadm_ClusterConfiguration(clusterCfg, &out.ClusterConfiguration, s)
}

View File

@ -67,7 +67,6 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
// SetDefaults_InitConfiguration assigns default values for the InitConfiguration
func SetDefaults_InitConfiguration(obj *InitConfiguration) {
SetDefaults_ClusterConfiguration(&obj.ClusterConfiguration)
SetDefaults_BootstrapTokens(obj)
SetDefaults_APIEndpoint(&obj.LocalAPIEndpoint)
}

View File

@ -28,12 +28,6 @@ import (
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 IS NOT uploaded to the `kubeadm-config` ConfigMap
// that is used by `kubeadm upgrade` for instance. These fields must be omitempty.

View File

@ -247,6 +247,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddConversionFunc((*kubeadm.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope)
}); err != nil {
return err
}
return nil
}
@ -661,9 +671,6 @@ func Convert_kubeadm_ImageMeta_To_v1beta2_ImageMeta(in *kubeadm.ImageMeta, out *
}
func autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
if err := Convert_v1beta2_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil {
return err
}
out.BootstrapTokens = *(*[]kubeadm.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens))
if err := Convert_v1beta2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err
@ -675,15 +682,8 @@ func autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *Init
return nil
}
// Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration is an autogenerated conversion function.
func Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
return autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s)
}
func autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error {
if err := Convert_kubeadm_ClusterConfiguration_To_v1beta2_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil {
return err
}
// 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_v1beta2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err
@ -695,11 +695,6 @@ func autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kube
return nil
}
// Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration is an autogenerated conversion function.
func Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error {
return autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in, out, s)
}
func autoConvert_v1beta2_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error {
if err := Convert_v1beta2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil {
return err

View File

@ -391,7 +391,6 @@ func (in *ImageMeta) DeepCopy() *ImageMeta {
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))

View File

@ -45,7 +45,6 @@ func SetObjectDefaults_ClusterStatus(in *ClusterStatus) {
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

@ -119,7 +119,7 @@ func newCmdCertsRenewal() *cobra.Command {
type renewFlags struct {
cfgPath string
kubeconfigPath string
cfg kubeadmapiv1beta2.InitConfiguration
cfg kubeadmapiv1beta2.ClusterConfiguration
useAPI bool
csrOnly bool
csrPath string
@ -127,11 +127,9 @@ type renewFlags struct {
func getRenewSubCommands(kdir string) []*cobra.Command {
flags := &renewFlags{
cfg: kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
// Setting kubernetes version to a default value in order to allow a not necessary internet lookup
KubernetesVersion: constants.CurrentKubernetesVersion.String(),
},
cfg: kubeadmapiv1beta2.ClusterConfiguration{
// Setting kubernetes version to a default value in order to allow a not necessary internet lookup
KubernetesVersion: constants.CurrentKubernetesVersion.String(),
},
}
// Default values for the cobra help text
@ -190,7 +188,7 @@ func addRenewFlags(cmd *cobra.Command, flags *renewFlags) {
}
func renewCert(flags *renewFlags, kdir string, handler *renewal.CertificateRenewHandler) {
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &flags.cfg)
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &kubeadmapiv1beta2.InitConfiguration{}, &flags.cfg)
kubeadmutil.CheckErr(err)
// Get a renewal manager for the given cluster configuration
@ -235,11 +233,9 @@ func renewCert(flags *renewFlags, kdir string, handler *renewal.CertificateRenew
// newCmdCertsExpiration creates a new `cert check-expiration` command.
func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
flags := &expirationFlags{
cfg: kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
// Setting kubernetes version to a default value in order to allow a not necessary internet lookup
KubernetesVersion: constants.CurrentKubernetesVersion.String(),
},
cfg: kubeadmapiv1beta2.ClusterConfiguration{
// Setting kubernetes version to a default value in order to allow a not necessary internet lookup
KubernetesVersion: constants.CurrentKubernetesVersion.String(),
},
}
// Default values for the cobra help text
@ -250,7 +246,7 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
Short: "Check certificates expiration for a Kubernetes cluster",
Long: expirationLongDesc,
Run: func(cmd *cobra.Command, args []string) {
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &flags.cfg)
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &kubeadmapiv1beta2.InitConfiguration{}, &flags.cfg)
kubeadmutil.CheckErr(err)
// Get a renewal manager for the given cluster configuration
@ -291,7 +287,7 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
type expirationFlags struct {
cfgPath string
cfg kubeadmapiv1beta2.InitConfiguration
cfg kubeadmapiv1beta2.ClusterConfiguration
}
func addExpirationFlags(cmd *cobra.Command, flags *expirationFlags) {

View File

@ -61,10 +61,12 @@ func newCmdKubeConfigUtility(out io.Writer) *cobra.Command {
// newCmdUserKubeConfig returns sub commands for kubeconfig phase
func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
cfg := &kubeadmapiv1beta2.InitConfiguration{}
initCfg := &kubeadmapiv1beta2.InitConfiguration{}
clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{}
// Default values for the cobra help text
kubeadmscheme.Scheme.Default(cfg)
kubeadmscheme.Scheme.Default(initCfg)
kubeadmscheme.Scheme.Default(clusterCfg)
var token, clientName string
var organizations []string
@ -80,8 +82,8 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
kubeadmutil.CheckErr(errors.New("missing required argument --client-name"))
}
// This call returns the ready-to-use configuration based on the default cfg populated by flags
internalcfg, err := configutil.DefaultedInitConfiguration(cfg)
// This call returns the ready-to-use configuration based on the defaults populated by flags
internalcfg, err := configutil.DefaultedInitConfiguration(initCfg, clusterCfg)
kubeadmutil.CheckErr(err)
// if the kubeconfig file for an additional user has to use a token, use it
@ -95,10 +97,14 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
},
}
// Add flags to the command
cmd.Flags().StringVar(&cfg.CertificatesDir, options.CertificatesDir, cfg.CertificatesDir, "The path where certificates are stored")
cmd.Flags().StringVar(&cfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, cfg.LocalAPIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on")
cmd.Flags().Int32Var(&cfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, cfg.LocalAPIEndpoint.BindPort, "The port the API server is accessible on")
// Add ClusterConfiguration backed flags to the command
cmd.Flags().StringVar(&clusterCfg.CertificatesDir, options.CertificatesDir, clusterCfg.CertificatesDir, "The path where certificates are stored")
// Add ClusterConfiguration backed flags to the command
cmd.Flags().StringVar(&initCfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, initCfg.LocalAPIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on")
cmd.Flags().Int32Var(&initCfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, initCfg.LocalAPIEndpoint.BindPort, "The port the API server is accessible on")
// Add command specific flags
cmd.Flags().StringVar(&token, options.TokenStr, token, "The token that should be used as the authentication mechanism for this kubeconfig, instead of client certificates")
cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of user. It will be used as the CN if client certificates are created")
cmd.Flags().StringSliceVar(&organizations, "org", organizations, "The orgnizations of the client certificate. It will be used as the O if client certificates are created")

View File

@ -75,7 +75,7 @@ func NewCmdSelfhosting(in io.Reader) *cobra.Command {
// getSelfhostingSubCommand returns sub commands for Self-hosting phase
func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
cfg := &kubeadmapiv1beta2.InitConfiguration{}
cfg := &kubeadmapiv1beta2.ClusterConfiguration{}
// Default values for the cobra help text
kubeadmscheme.Scheme.Default(cfg)
@ -124,10 +124,10 @@ func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing LoadOrDefaultInitConfiguration
phases.SetKubernetesVersion(&cfg.ClusterConfiguration)
phases.SetKubernetesVersion(cfg)
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, cfg)
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, &kubeadmapiv1beta2.InitConfiguration{}, cfg)
kubeadmutil.CheckErr(err)
// Converts the Static Pod-hosted control plane into a self-hosted one

View File

@ -176,17 +176,17 @@ func getSupportedComponentConfigAPIObjects() []string {
}
func getDefaultedInitConfig() (*kubeadmapi.InitConfiguration, error) {
return configutil.DefaultedInitConfiguration(&kubeadmapiv1beta2.InitConfiguration{
// TODO: Probably move to getDefaultedClusterConfig?
initCfg := &kubeadmapiv1beta2.InitConfiguration{
LocalAPIEndpoint: kubeadmapiv1beta2.APIEndpoint{AdvertiseAddress: "1.2.3.4"},
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1),
},
BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{placeholderToken},
BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{placeholderToken},
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
CRISocket: constants.DefaultDockerCRISocket, // avoid CRI detection
},
})
}
clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: constants.CurrentKubernetesVersion.String(), // avoid going to the Internet for the current Kubernetes version
}
return configutil.DefaultedInitConfiguration(initCfg, clusterCfg)
}
func getDefaultInitConfigBytes() ([]byte, error) {
@ -341,8 +341,11 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
// NewCmdConfigUploadFromFlags returns cobra.Command for "kubeadm config upload from-flags" command
// Deprecated: please see kubeadm init phase upload-config
func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.Command {
cfg := &kubeadmapiv1beta2.InitConfiguration{}
kubeadmscheme.Scheme.Default(cfg)
initCfg := &kubeadmapiv1beta2.InitConfiguration{}
kubeadmscheme.Scheme.Default(initCfg)
clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{}
kubeadmscheme.Scheme.Default(clusterCfg)
var featureGatesString string
@ -360,7 +363,7 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C
Run: func(cmd *cobra.Command, args []string) {
var err error
klog.V(1).Infoln("[config] creating new FeatureGates")
if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
if clusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
kubeadmutil.CheckErr(err)
}
klog.V(1).Infoln("[config] retrieving ClientSet from file")
@ -369,11 +372,11 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing DefaultedInitConfiguration
phaseutil.SetKubernetesVersion(&cfg.ClusterConfiguration)
phaseutil.SetKubernetesVersion(clusterCfg)
// Default both statically and dynamically, convert to internal API type, and validate everything
klog.V(1).Infoln("[config] converting to internal API type")
internalcfg, err := configutil.DefaultedInitConfiguration(cfg)
internalcfg, err := configutil.DefaultedInitConfiguration(initCfg, clusterCfg)
kubeadmutil.CheckErr(err)
// Finally, upload the configuration
@ -382,7 +385,8 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C
kubeadmutil.CheckErr(err)
},
}
AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
AddInitConfigFlags(cmd.PersistentFlags(), initCfg)
AddClusterConfigFlags(cmd.PersistentFlags(), clusterCfg, &featureGatesString)
return cmd
}
@ -413,8 +417,10 @@ func NewCmdConfigImages(out io.Writer) *cobra.Command {
// NewCmdConfigImagesPull returns the `kubeadm config images pull` command
func NewCmdConfigImagesPull() *cobra.Command {
externalcfg := &kubeadmapiv1beta2.InitConfiguration{}
kubeadmscheme.Scheme.Default(externalcfg)
externalClusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{}
kubeadmscheme.Scheme.Default(externalClusterCfg)
externalInitCfg := &kubeadmapiv1beta2.InitConfiguration{}
kubeadmscheme.Scheme.Default(externalInitCfg)
var cfgPath, featureGatesString string
var err error
@ -422,17 +428,17 @@ func NewCmdConfigImagesPull() *cobra.Command {
Use: "pull",
Short: "Pull images used by kubeadm",
Run: func(_ *cobra.Command, _ []string) {
externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
externalClusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
kubeadmutil.CheckErr(err)
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, externalcfg)
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, externalInitCfg, externalClusterCfg)
kubeadmutil.CheckErr(err)
containerRuntime, err := utilruntime.NewContainerRuntime(utilsexec.New(), internalcfg.NodeRegistration.CRISocket)
kubeadmutil.CheckErr(err)
PullControlPlaneImages(containerRuntime, &internalcfg.ClusterConfiguration)
},
}
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString)
cmdutil.AddCRISocketFlag(cmd.PersistentFlags(), &externalcfg.NodeRegistration.CRISocket)
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalClusterCfg, &cfgPath, &featureGatesString)
cmdutil.AddCRISocketFlag(cmd.PersistentFlags(), &externalInitCfg.NodeRegistration.CRISocket)
return cmd
}
@ -465,7 +471,7 @@ func PullControlPlaneImages(runtime utilruntime.ContainerRuntime, cfg *kubeadmap
// NewCmdConfigImagesList returns the "kubeadm config images list" command
func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Command {
externalcfg := &kubeadmapiv1beta2.InitConfiguration{}
externalcfg := &kubeadmapiv1beta2.ClusterConfiguration{}
kubeadmscheme.Scheme.Default(externalcfg)
var cfgPath, featureGatesString string
var err error
@ -480,7 +486,7 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman
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) {
externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
externalcfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString)
kubeadmutil.CheckErr(err)
imagesList, err := NewImagesList(cfgPath, externalcfg)
kubeadmutil.CheckErr(err)
@ -492,8 +498,15 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman
}
// NewImagesList returns the underlying struct for the "kubeadm config images list" command
func NewImagesList(cfgPath string, cfg *kubeadmapiv1beta2.InitConfiguration) (*ImagesList, error) {
initcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, cfg)
func NewImagesList(cfgPath string, cfg *kubeadmapiv1beta2.ClusterConfiguration) (*ImagesList, error) {
// Avoid running the CRI auto-detection code as we don't need it
versionedInitCfg := &kubeadmapiv1beta2.InitConfiguration{
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
CRISocket: constants.DefaultDockerCRISocket,
},
}
initcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, versionedInitCfg, cfg)
if err != nil {
return nil, errors.Wrap(err, "could not convert cfg to an internal cfg")
}
@ -519,8 +532,8 @@ 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 *kubeadmapiv1beta2.InitConfiguration, cfgPath *string, featureGatesString *string) {
options.AddKubernetesVersionFlag(flagSet, &cfg.ClusterConfiguration.KubernetesVersion)
func AddImagesCommonConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.ClusterConfiguration, cfgPath *string, featureGatesString *string) {
options.AddKubernetesVersionFlag(flagSet, &cfg.KubernetesVersion)
options.AddFeatureGatesStringFlag(flagSet, featureGatesString)
options.AddImageMetaFlags(flagSet, &cfg.ImageRepository)
flagSet.StringVar(cfgPath, "config", *cfgPath, "Path to kubeadm config file.")

View File

@ -106,10 +106,8 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
t.Fatalf("Failed writing a config file: %v", err)
}
i, err := NewImagesList(configFilePath, &kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
i, err := NewImagesList(configFilePath, &kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
})
if err != nil {
t.Fatalf("Failed getting the kubeadm images command: %v", err)
@ -135,61 +133,41 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
func TestConfigImagesListRunWithoutPath(t *testing.T) {
testcases := []struct {
name string
cfg kubeadmapiv1beta2.InitConfiguration
cfg kubeadmapiv1beta2.ClusterConfiguration
expectedImages int
}{
{
name: "empty config",
expectedImages: defaultNumberOfImages,
cfg: kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
CRISocket: constants.DefaultDockerCRISocket,
},
cfg: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
},
{
name: "external etcd configuration",
cfg: kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
Etcd: kubeadmapiv1beta2.Etcd{
External: &kubeadmapiv1beta2.ExternalEtcd{
Endpoints: []string{"https://some.etcd.com:2379"},
},
cfg: kubeadmapiv1beta2.ClusterConfiguration{
Etcd: kubeadmapiv1beta2.Etcd{
External: &kubeadmapiv1beta2.ExternalEtcd{
Endpoints: []string{"https://some.etcd.com:2379"},
},
KubernetesVersion: dummyKubernetesVersion,
},
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
CRISocket: constants.DefaultDockerCRISocket,
},
KubernetesVersion: dummyKubernetesVersion,
},
expectedImages: defaultNumberOfImages - 1,
},
{
name: "coredns enabled",
cfg: kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
CRISocket: constants.DefaultDockerCRISocket,
},
cfg: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
},
expectedImages: defaultNumberOfImages,
},
{
name: "kube-dns enabled",
cfg: kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
DNS: kubeadmapiv1beta2.DNS{
Type: kubeadmapiv1beta2.KubeDNS,
},
},
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
CRISocket: constants.DefaultDockerCRISocket,
cfg: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
DNS: kubeadmapiv1beta2.DNS{
Type: kubeadmapiv1beta2.KubeDNS,
},
},
expectedImages: defaultNumberOfImages + 2,

View File

@ -95,7 +95,8 @@ type initOptions struct {
featureGatesString string
ignorePreflightErrors []string
bto *options.BootstrapTokenOptions
externalcfg *kubeadmapiv1beta2.InitConfiguration
externalInitCfg *kubeadmapiv1beta2.InitConfiguration
externalClusterCfg *kubeadmapiv1beta2.ClusterConfiguration
uploadCerts bool
skipCertificateKeyPrint bool
}
@ -151,18 +152,19 @@ func NewCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command {
// adds flags to the init command
// init command local flags could be eventually inherited by the sub-commands automatically generated for phases
AddInitConfigFlags(cmd.Flags(), initOptions.externalcfg, &initOptions.featureGatesString)
AddInitConfigFlags(cmd.Flags(), initOptions.externalInitCfg)
AddClusterConfigFlags(cmd.Flags(), initOptions.externalClusterCfg, &initOptions.featureGatesString)
AddInitOtherFlags(cmd.Flags(), initOptions)
initOptions.bto.AddTokenFlag(cmd.Flags())
initOptions.bto.AddTTLFlag(cmd.Flags())
options.AddImageMetaFlags(cmd.Flags(), &initOptions.externalcfg.ImageRepository)
options.AddImageMetaFlags(cmd.Flags(), &initOptions.externalClusterCfg.ImageRepository)
// defines additional flag that are not used by the init command but that could be eventually used
// by the sub-commands automatically generated for phases
initRunner.SetAdditionalFlags(func(flags *flag.FlagSet) {
options.AddKubeConfigFlag(flags, &initOptions.kubeconfigPath)
options.AddKubeConfigDirFlag(flags, &initOptions.kubeconfigDir)
options.AddControlPlanExtraArgsFlags(flags, &initOptions.externalcfg.APIServer.ExtraArgs, &initOptions.externalcfg.ControllerManager.ExtraArgs, &initOptions.externalcfg.Scheduler.ExtraArgs)
options.AddControlPlanExtraArgsFlags(flags, &initOptions.externalClusterCfg.APIServer.ExtraArgs, &initOptions.externalClusterCfg.ControllerManager.ExtraArgs, &initOptions.externalClusterCfg.Scheduler.ExtraArgs)
})
// initialize the workflow runner with the list of phases
@ -193,7 +195,7 @@ func NewCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command {
}
// AddInitConfigFlags adds init flags bound to the config to the specified flagset
func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfiguration, featureGatesString *string) {
func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfiguration) {
flagSet.StringVar(
&cfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, cfg.LocalAPIEndpoint.AdvertiseAddress,
"The IP address the API Server will advertise it's listening on. If not set the default network interface will be used.",
@ -202,6 +204,19 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfig
&cfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, cfg.LocalAPIEndpoint.BindPort,
"Port for the API Server to bind to.",
)
flagSet.StringVar(
&cfg.NodeRegistration.Name, options.NodeName, cfg.NodeRegistration.Name,
`Specify the node name.`,
)
flagSet.StringVar(
&cfg.CertificateKey, options.CertificateKey, "",
"Key used to encrypt the control-plane certificates in the kubeadm-certs Secret.",
)
cmdutil.AddCRISocketFlag(flagSet, &cfg.NodeRegistration.CRISocket)
}
// AddClusterConfigFlags adds cluster flags bound to the config to the specified flagset
func AddClusterConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.ClusterConfiguration, featureGatesString *string) {
flagSet.StringVar(
&cfg.Networking.ServiceSubnet, options.NetworkingServiceSubnet, cfg.Networking.ServiceSubnet,
"Use alternative range of IP address for service VIPs.",
@ -225,15 +240,6 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfig
&cfg.APIServer.CertSANs, options.APIServerCertSANs, cfg.APIServer.CertSANs,
`Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.`,
)
flagSet.StringVar(
&cfg.NodeRegistration.Name, options.NodeName, cfg.NodeRegistration.Name,
`Specify the node name.`,
)
flagSet.StringVar(
&cfg.CertificateKey, options.CertificateKey, "",
"Key used to encrypt the control-plane certificates in the kubeadm-certs Secret.",
)
cmdutil.AddCRISocketFlag(flagSet, &cfg.NodeRegistration.CRISocket)
options.AddFeatureGatesStringFlag(flagSet, featureGatesString)
}
@ -266,19 +272,23 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, initOptions *initOptions) {
// newInitOptions returns a struct ready for being used for creating cmd init flags.
func newInitOptions() *initOptions {
// initialize the public kubeadm config API by applying defaults
externalcfg := &kubeadmapiv1beta2.InitConfiguration{}
kubeadmscheme.Scheme.Default(externalcfg)
externalInitCfg := &kubeadmapiv1beta2.InitConfiguration{}
kubeadmscheme.Scheme.Default(externalInitCfg)
externalClusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{}
kubeadmscheme.Scheme.Default(externalClusterCfg)
// Create the options object for the bootstrap token-related flags, and override the default value for .Description
bto := options.NewBootstrapTokenOptions()
bto.Description = "The default bootstrap token generated by 'kubeadm init'."
return &initOptions{
externalcfg: externalcfg,
bto: bto,
kubeconfigDir: kubeadmconstants.KubernetesDir,
kubeconfigPath: kubeadmconstants.GetAdminKubeConfigPath(),
uploadCerts: false,
externalInitCfg: externalInitCfg,
externalClusterCfg: externalClusterCfg,
bto: bto,
kubeconfigDir: kubeadmconstants.KubernetesDir,
kubeconfigPath: kubeadmconstants.GetAdminKubeConfigPath(),
uploadCerts: false,
}
}
@ -287,12 +297,13 @@ func newInitOptions() *initOptions {
// options into the internal InitConfiguration type that is used as input all the phases in the kubeadm init workflow
func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io.Writer) (*initData, error) {
// Re-apply defaults to the public kubeadm API (this will set only values not exposed/not set as a flags)
kubeadmscheme.Scheme.Default(options.externalcfg)
kubeadmscheme.Scheme.Default(options.externalInitCfg)
kubeadmscheme.Scheme.Default(options.externalClusterCfg)
// Validate standalone flags values and/or combination of flags and then assigns
// validated values to the public kubeadm config API when applicable
var err error
if options.externalcfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, options.featureGatesString); err != nil {
if options.externalClusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, options.featureGatesString); err != nil {
return nil, err
}
@ -300,13 +311,13 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io
return nil, err
}
if err = options.bto.ApplyTo(options.externalcfg); err != nil {
if err = options.bto.ApplyTo(options.externalInitCfg); err != nil {
return nil, err
}
// Either use the config file if specified, or convert public kubeadm API to the internal InitConfiguration
// and validates InitConfiguration
cfg, err := configutil.LoadOrDefaultInitConfiguration(options.cfgPath, options.externalcfg)
cfg, err := configutil.LoadOrDefaultInitConfiguration(options.cfgPath, options.externalInitCfg, options.externalClusterCfg)
if err != nil {
return nil, err
}
@ -319,11 +330,11 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io
cfg.NodeRegistration.IgnorePreflightErrors = ignorePreflightErrorsSet.List()
// override node name and CRI socket from the command line options
if options.externalcfg.NodeRegistration.Name != "" {
cfg.NodeRegistration.Name = options.externalcfg.NodeRegistration.Name
if options.externalInitCfg.NodeRegistration.Name != "" {
cfg.NodeRegistration.Name = options.externalInitCfg.NodeRegistration.Name
}
if options.externalcfg.NodeRegistration.CRISocket != "" {
cfg.NodeRegistration.CRISocket = options.externalcfg.NodeRegistration.CRISocket
if options.externalInitCfg.NodeRegistration.CRISocket != "" {
cfg.NodeRegistration.CRISocket = options.externalInitCfg.NodeRegistration.CRISocket
}
if err := configutil.VerifyAPIServerBindAddress(cfg.LocalAPIEndpoint.AdvertiseAddress); err != nil {

View File

@ -40,7 +40,6 @@ import (
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
phaseutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
@ -209,10 +208,14 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
}
// RunCreateToken generates a new bootstrap token and stores it as a secret on the server.
func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, cfg *kubeadmapiv1beta2.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error {
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
// of the version from the internet when executing LoadOrDefaultInitConfiguration
phaseutil.SetKubernetesVersion(&cfg.ClusterConfiguration)
func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, initCfg *kubeadmapiv1beta2.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error {
// ClusterConfiguration is needed just for the call to LoadOrDefaultInitConfiguration
clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{
// KubernetesVersion is not used, but we set this explicitly to avoid
// the lookup of the version from the internet when executing LoadOrDefaultInitConfiguration
KubernetesVersion: kubeadmconstants.CurrentKubernetesVersion.String(),
}
kubeadmscheme.Scheme.Default(clusterCfg)
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
klog.V(1).Infoln("[token] loading configurations")
@ -220,9 +223,9 @@ func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, c
// In fact, we don't do any CRI ops at all.
// This is just to force skipping the CRI detection.
// Ref: https://github.com/kubernetes/kubeadm/issues/1559
cfg.NodeRegistration.CRISocket = kubeadmconstants.DefaultDockerCRISocket
initCfg.NodeRegistration.CRISocket = kubeadmconstants.DefaultDockerCRISocket
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, cfg)
internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, initCfg, clusterCfg)
if err != nil {
return err
}

View File

@ -32,7 +32,6 @@ import (
core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/clientcmd"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
)
const (
@ -160,11 +159,6 @@ func TestRunCreateToken(t *testing.T) {
}
cfg := &kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
// KubernetesVersion is not used, but we set this explicitly to avoid
// the lookup of the version from the internet when executing LoadOrDefaultInitConfiguration
KubernetesVersion: constants.MinimumControlPlaneVersion.String(),
},
BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{
{
Token: bts,
@ -176,8 +170,10 @@ func TestRunCreateToken(t *testing.T) {
}
err = RunCreateToken(&buf, fakeClient, "", cfg, tc.printJoin, "")
if (err != nil) != tc.expectedError {
t.Errorf("Test case %s: RunCreateToken expected error: %v, saw: %v", tc.name, tc.expectedError, (err != nil))
if tc.expectedError && err == nil {
t.Error("unexpected success")
} else if !tc.expectedError && err != nil {
t.Errorf("unexpected error: %v", err)
}
})
}

View File

@ -179,13 +179,13 @@ func TestEnsureProxyAddon(t *testing.T) {
AdvertiseAddress: "1.2.3.4",
BindPort: 1234,
},
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
Networking: kubeadmapiv1beta2.Networking{
PodSubnet: "5.6.7.8/24",
},
ImageRepository: "someRepo",
KubernetesVersion: constants.MinimumControlPlaneVersion.String(),
}
controlPlaneClusterConfig := &kubeadmapiv1beta2.ClusterConfiguration{
Networking: kubeadmapiv1beta2.Networking{
PodSubnet: "5.6.7.8/24",
},
ImageRepository: "someRepo",
KubernetesVersion: constants.MinimumControlPlaneVersion.String(),
}
// Simulate an error if necessary
@ -198,10 +198,10 @@ func TestEnsureProxyAddon(t *testing.T) {
controlPlaneConfig.LocalAPIEndpoint.AdvertiseAddress = "1.2.3"
case IPv6SetBindAddress:
controlPlaneConfig.LocalAPIEndpoint.AdvertiseAddress = "1:2::3:4"
controlPlaneConfig.Networking.PodSubnet = "2001:101::/96"
controlPlaneClusterConfig.Networking.PodSubnet = "2001:101::/96"
}
intControlPlane, err := configutil.DefaultedInitConfiguration(controlPlaneConfig)
intControlPlane, err := configutil.DefaultedInitConfiguration(controlPlaneConfig, controlPlaneClusterConfig)
if err != nil {
t.Errorf("test failed to convert external to internal version")
return

View File

@ -69,9 +69,6 @@ func TestUploadConfiguration(t *testing.T) {
LocalAPIEndpoint: kubeadmapiv1beta2.APIEndpoint{
AdvertiseAddress: "1.2.3.4",
},
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: kubeadmconstants.MinimumControlPlaneVersion.WithPatch(10).String(),
},
BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{
{
Token: &kubeadmapiv1beta2.BootstrapTokenString{
@ -85,7 +82,10 @@ func TestUploadConfiguration(t *testing.T) {
CRISocket: "/var/run/custom-cri.sock",
},
}
cfg, err := configutil.DefaultedInitConfiguration(initialcfg)
clustercfg := &kubeadmapiv1beta2.ClusterConfiguration{
KubernetesVersion: kubeadmconstants.MinimumControlPlaneVersion.WithPatch(10).String(),
}
cfg, err := configutil.DefaultedInitConfiguration(initialcfg, clustercfg)
// cleans up component config to make cfg and decodedcfg comparable (now component config are not stored anymore in kubeadm-config config map)
cfg.ComponentConfigs = kubeadmapi.ComponentConfigs{}

View File

@ -125,11 +125,9 @@ func TestLowercaseSANs(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cfg := &kubeadmapiv1beta2.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{
APIServer: kubeadmapiv1beta2.APIServer{
CertSANs: test.in,
},
cfg := &kubeadmapiv1beta2.ClusterConfiguration{
APIServer: kubeadmapiv1beta2.APIServer{
CertSANs: test.in,
},
}

View File

@ -162,13 +162,16 @@ func SetClusterDynamicDefaults(cfg *kubeadmapi.ClusterConfiguration, advertiseAd
}
// DefaultedInitConfiguration takes a versioned init config (often populated by flags), defaults it and converts it into internal InitConfiguration
func DefaultedInitConfiguration(defaultversionedcfg *kubeadmapiv1beta2.InitConfiguration) (*kubeadmapi.InitConfiguration, error) {
func DefaultedInitConfiguration(versionedInitCfg *kubeadmapiv1beta2.InitConfiguration, versionedClusterCfg *kubeadmapiv1beta2.ClusterConfiguration) (*kubeadmapi.InitConfiguration, error) {
internalcfg := &kubeadmapi.InitConfiguration{}
// 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)
kubeadmscheme.Scheme.Default(versionedInitCfg)
kubeadmscheme.Scheme.Convert(versionedInitCfg, internalcfg, nil)
kubeadmscheme.Scheme.Default(versionedClusterCfg)
kubeadmscheme.Scheme.Convert(versionedClusterCfg, &internalcfg.ClusterConfiguration, nil)
// Applies dynamic defaults to settings not provided with flags
if err := SetInitDynamicDefaults(internalcfg); err != nil {
@ -194,18 +197,18 @@ func LoadInitConfigurationFromFile(cfgPath string) (*kubeadmapi.InitConfiguratio
}
// LoadOrDefaultInitConfiguration takes a path to a config file and a versioned configuration that can serve as the default config
// If cfgPath is specified, defaultversionedcfg will always get overridden. Otherwise, the default config (often populated by flags) will be used.
// Then the external, versioned configuration is defaulted and converted to the internal type.
// If cfgPath is specified, the versioned configs will always get overridden with the one in the file (specified by cfgPath).
// The the external, versioned configuration is defaulted and converted to the internal type.
// Right thereafter, the configuration is defaulted again with dynamic values (like IP addresses of a machine, etc)
// Lastly, the internal config is validated and returned.
func LoadOrDefaultInitConfiguration(cfgPath string, defaultversionedcfg *kubeadmapiv1beta2.InitConfiguration) (*kubeadmapi.InitConfiguration, error) {
func LoadOrDefaultInitConfiguration(cfgPath string, versionedInitCfg *kubeadmapiv1beta2.InitConfiguration, versionedClusterCfg *kubeadmapiv1beta2.ClusterConfiguration) (*kubeadmapi.InitConfiguration, error) {
if cfgPath != "" {
// Loads configuration from config file, if provided
// Nb. --config overrides command line flags
return LoadInitConfigurationFromFile(cfgPath)
}
return DefaultedInitConfiguration(defaultversionedcfg)
return DefaultedInitConfiguration(versionedInitCfg, versionedClusterCfg)
}
// BytesToInitConfiguration converts a byte slice to an internal, defaulted and validated InitConfiguration object.

View File

@ -157,7 +157,7 @@ func AssertError(t *testing.T, err error, expected string) {
// GetDefaultInternalConfig returns a defaulted kubeadmapi.InitConfiguration
func GetDefaultInternalConfig(t *testing.T) *kubeadmapi.InitConfiguration {
internalcfg, err := configutil.DefaultedInitConfiguration(&kubeadmapiv1beta2.InitConfiguration{})
internalcfg, err := configutil.DefaultedInitConfiguration(&kubeadmapiv1beta2.InitConfiguration{}, &kubeadmapiv1beta2.ClusterConfiguration{})
if err != nil {
t.Fatalf("unexpected error getting default config: %v", err)
}