Merge pull request #69617 from rosti/config-defaults-split

kubeadm: Introduce config print init/join-defaults
pull/58/head
k8s-ci-robot 2018-10-20 08:04:53 -07:00 committed by GitHub
commit a6e273214b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 215 additions and 15 deletions

View File

@ -95,9 +95,11 @@ go_test(
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
"//cmd/kubeadm/app/componentconfigs:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/preflight:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library",
"//cmd/kubeadm/app/util/runtime:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",

View File

@ -50,8 +50,8 @@ import (
)
var (
// sillyToken is only set statically to make kubeadm not randomize the token on every run
sillyToken = kubeadmapiv1beta1.BootstrapToken{
// placeholderToken is only set statically to make kubeadm not randomize the token on every run
placeholderToken = kubeadmapiv1beta1.BootstrapToken{
Token: &kubeadmapiv1beta1.BootstrapTokenString{
ID: "abcdef",
Secret: "0123456789abcdef",
@ -83,6 +83,7 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
options.AddKubeConfigFlag(cmd.PersistentFlags(), &kubeConfigFile)
kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile)
cmd.AddCommand(NewCmdConfigPrint(out))
cmd.AddCommand(NewCmdConfigPrintDefault(out))
cmd.AddCommand(NewCmdConfigMigrate(out))
cmd.AddCommand(NewCmdConfigUpload(out, &kubeConfigFile))
@ -91,6 +92,63 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
return cmd
}
// NewCmdConfigPrint returns cobra.Command for "kubeadm config print" command
func NewCmdConfigPrint(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "print",
Short: "Print configuration",
Long: "This command prints configurations for subcommands provided.",
RunE: cmdutil.SubCmdRunE("print"),
}
cmd.AddCommand(NewCmdConfigPrintInitDefaults(out))
cmd.AddCommand(NewCmdConfigPrintJoinDefaults(out))
return cmd
}
// NewCmdConfigPrintInitDefaults returns cobra.Command for "kubeadm config print init-defaults" command
func NewCmdConfigPrintInitDefaults(out io.Writer) *cobra.Command {
return newCmdConfigPrintActionDefaults(out, "init", getDefaultInitConfigBytes)
}
// NewCmdConfigPrintJoinDefaults returns cobra.Command for "kubeadm config print join-defaults" command
func NewCmdConfigPrintJoinDefaults(out io.Writer) *cobra.Command {
return newCmdConfigPrintActionDefaults(out, "join", getDefaultNodeConfigBytes)
}
func newCmdConfigPrintActionDefaults(out io.Writer, action string, configBytesProc func() ([]byte, error)) *cobra.Command {
componentConfigs := []string{}
cmd := &cobra.Command{
Use: fmt.Sprintf("%s-defaults", action),
Short: fmt.Sprintf("Print default %s configuration, that can be used for 'kubeadm %s'", action, action),
Long: fmt.Sprintf(dedent.Dedent(`
This command prints objects such as the default %s configuration that is used for 'kubeadm %s'.
Note that sensitive values like the Bootstrap Token fields are replaced with placeholder values like %q in order to pass validation but
not perform the real computation for creating a token.
`), action, action, placeholderToken),
Run: func(cmd *cobra.Command, args []string) {
runConfigPrintActionDefaults(out, componentConfigs, configBytesProc)
},
}
cmd.Flags().StringSliceVar(&componentConfigs, "component-configs", componentConfigs,
fmt.Sprintf("A comma-separated list for component config API objects to print the default values for. Available values: %v. If this flag is not set, no component configs will be printed.", getSupportedComponentConfigAPIObjects()))
return cmd
}
func runConfigPrintActionDefaults(out io.Writer, componentConfigs []string, configBytesProc func() ([]byte, error)) {
initialConfig, err := configBytesProc()
kubeadmutil.CheckErr(err)
allBytes := [][]byte{initialConfig}
for _, componentConfig := range componentConfigs {
cfgBytes, err := getDefaultComponentConfigAPIObjectBytes(componentConfig)
kubeadmutil.CheckErr(err)
allBytes = append(allBytes, cfgBytes)
}
fmt.Fprint(out, string(bytes.Join(allBytes, []byte(constants.YAMLDocumentSeparator))))
}
// NewCmdConfigPrintDefault returns cobra.Command for "kubeadm config print-default" command
func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
apiObjects := []string{}
@ -104,9 +162,10 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
For documentation visit: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3
Note that sensitive values like the Bootstrap Token fields are replaced with silly values like %q in order to pass validation but
Note that sensitive values like the Bootstrap Token fields are replaced with placeholder values like %q in order to pass validation but
not perform the real computation for creating a token.
`), sillyToken),
`), placeholderToken),
Deprecated: "Please, use `kubeadm config print` instead.",
Run: func(cmd *cobra.Command, args []string) {
if len(apiObjects) == 0 {
apiObjects = getSupportedAPIObjects()
@ -125,13 +184,21 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
return cmd
}
func getDefaultComponentConfigAPIObjectBytes(apiObject string) ([]byte, error) {
registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)]
if !ok {
return []byte{}, fmt.Errorf("--component-configs needs to contain some of %v", getSupportedComponentConfigAPIObjects())
}
return getDefaultComponentConfigBytes(registration)
}
func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
switch apiObject {
case constants.InitConfigurationKind:
return getDefaultInitConfigBytes(constants.InitConfigurationKind)
return getDefaultInitConfigBytesByKind(constants.InitConfigurationKind)
case constants.ClusterConfigurationKind:
return getDefaultInitConfigBytes(constants.ClusterConfigurationKind)
return getDefaultInitConfigBytesByKind(constants.ClusterConfigurationKind)
case constants.JoinConfigurationKind:
return getDefaultNodeConfigBytes()
@ -146,15 +213,23 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
}
}
// getSupportedAPIObjects returns all currently supported API object names
func getSupportedAPIObjects() []string {
objects := []string{constants.InitConfigurationKind, constants.ClusterConfigurationKind, constants.JoinConfigurationKind}
// getSupportedComponentConfigAPIObjects returns all currently supported component config API object names
func getSupportedComponentConfigAPIObjects() []string {
objects := []string{}
for componentType := range componentconfigs.Known {
objects = append(objects, string(componentType))
}
return objects
}
// getSupportedAPIObjects returns all currently supported API object names
func getSupportedAPIObjects() []string {
baseObjects := []string{constants.InitConfigurationKind, constants.ClusterConfigurationKind, constants.JoinConfigurationKind}
objects := getSupportedComponentConfigAPIObjects()
objects = append(objects, baseObjects...)
return objects
}
// getAllAPIObjectNames returns currently supported API object names and their historical aliases
// NB. currently there is no historical supported API objects, but we keep this function for future changes
func getAllAPIObjectNames() []string {
@ -171,18 +246,21 @@ func getDefaultedInitConfig() (*kubeadmapi.InitConfiguration, error) {
ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{
KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1),
},
BootstrapTokens: []kubeadmapiv1beta1.BootstrapToken{sillyToken},
BootstrapTokens: []kubeadmapiv1beta1.BootstrapToken{placeholderToken},
})
}
// TODO: This is now invoked for both InitConfiguration and ClusterConfiguration, we should make separate versions of it
func getDefaultInitConfigBytes(kind string) ([]byte, error) {
func getDefaultInitConfigBytes() ([]byte, error) {
internalcfg, err := getDefaultedInitConfig()
if err != nil {
return []byte{}, err
}
b, err := configutil.MarshalKubeadmConfigObject(internalcfg)
return configutil.MarshalKubeadmConfigObject(internalcfg)
}
func getDefaultInitConfigBytesByKind(kind string) ([]byte, error) {
b, err := getDefaultInitConfigBytes()
if err != nil {
return []byte{}, err
}
@ -197,7 +275,7 @@ func getDefaultNodeConfigBytes() ([]byte, error) {
internalcfg, err := configutil.JoinConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1beta1.JoinConfiguration{
Discovery: kubeadmapiv1beta1.Discovery{
BootstrapToken: &kubeadmapiv1beta1.BootstrapTokenDiscovery{
Token: sillyToken.Token.String(),
Token: placeholderToken.Token.String(),
APIServerEndpoints: []string{"kube-apiserver:6443"},
UnsafeSkipCAVerification: true, // TODO: UnsafeSkipCAVerification: true needs to be set for validation to pass, but shouldn't be recommended as the default
},

View File

@ -18,17 +18,24 @@ package cmd_test
import (
"bytes"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"sort"
"strings"
"testing"
"github.com/renstrom/dedent"
"github.com/spf13/cobra"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd"
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime"
"k8s.io/utils/exec"
@ -272,3 +279,96 @@ func tempConfig(t *testing.T, config []byte) (string, func()) {
os.RemoveAll(tmpDir)
}
}
func TestNewCmdConfigPrintActionDefaults(t *testing.T) {
tests := []struct {
name string
expectedKinds []string // need to be sorted
componentConfigs string
cmdProc func(out io.Writer) *cobra.Command
}{
{
name: "InitConfiguration: No component configs",
expectedKinds: []string{
constants.ClusterConfigurationKind,
constants.InitConfigurationKind,
},
cmdProc: cmd.NewCmdConfigPrintInitDefaults,
},
{
name: "InitConfiguration: KubeProxyConfiguration",
expectedKinds: []string{
constants.ClusterConfigurationKind,
constants.InitConfigurationKind,
string(componentconfigs.KubeProxyConfigurationKind),
},
componentConfigs: "KubeProxyConfiguration",
cmdProc: cmd.NewCmdConfigPrintInitDefaults,
},
{
name: "InitConfiguration: KubeProxyConfiguration and KubeletConfiguration",
expectedKinds: []string{
constants.ClusterConfigurationKind,
constants.InitConfigurationKind,
string(componentconfigs.KubeProxyConfigurationKind),
string(componentconfigs.KubeletConfigurationKind),
},
componentConfigs: "KubeProxyConfiguration,KubeletConfiguration",
cmdProc: cmd.NewCmdConfigPrintInitDefaults,
},
{
name: "JoinConfiguration: No component configs",
expectedKinds: []string{
constants.JoinConfigurationKind,
},
cmdProc: cmd.NewCmdConfigPrintJoinDefaults,
},
{
name: "JoinConfiguration: KubeProxyConfiguration",
expectedKinds: []string{
constants.JoinConfigurationKind,
string(componentconfigs.KubeProxyConfigurationKind),
},
componentConfigs: "KubeProxyConfiguration",
cmdProc: cmd.NewCmdConfigPrintJoinDefaults,
},
{
name: "JoinConfiguration: KubeProxyConfiguration and KubeletConfiguration",
expectedKinds: []string{
constants.JoinConfigurationKind,
string(componentconfigs.KubeProxyConfigurationKind),
string(componentconfigs.KubeletConfigurationKind),
},
componentConfigs: "KubeProxyConfiguration,KubeletConfiguration",
cmdProc: cmd.NewCmdConfigPrintJoinDefaults,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var output bytes.Buffer
command := test.cmdProc(&output)
if err := command.Flags().Set("component-configs", test.componentConfigs); err != nil {
t.Fatalf("failed to set component-configs flag")
}
command.Run(nil, nil)
gvkmap, err := kubeadmutil.SplitYAMLDocuments(output.Bytes())
if err != nil {
t.Fatalf("unexpected failure of SplitYAMLDocuments: %v", err)
}
gotKinds := []string{}
for gvk := range gvkmap {
gotKinds = append(gotKinds, gvk.Kind)
}
sort.Strings(gotKinds)
if !reflect.DeepEqual(gotKinds, test.expectedKinds) {
t.Fatalf("kinds not matching:\n\texpectedKinds: %v\n\tgotKinds: %v\n", test.expectedKinds, gotKinds)
}
})
}
}

View File

@ -74,7 +74,9 @@ docs/admin/kubeadm_config_images.md
docs/admin/kubeadm_config_images_list.md
docs/admin/kubeadm_config_images_pull.md
docs/admin/kubeadm_config_migrate.md
docs/admin/kubeadm_config_print-default.md
docs/admin/kubeadm_config_print.md
docs/admin/kubeadm_config_print_init-defaults.md
docs/admin/kubeadm_config_print_join-defaults.md
docs/admin/kubeadm_config_upload.md
docs/admin/kubeadm_config_upload_from-file.md
docs/admin/kubeadm_config_upload_from-flags.md
@ -172,6 +174,9 @@ docs/man/man1/kubeadm-config-images-pull.1
docs/man/man1/kubeadm-config-images.1
docs/man/man1/kubeadm-config-migrate.1
docs/man/man1/kubeadm-config-print-default.1
docs/man/man1/kubeadm-config-print-init-defaults.1
docs/man/man1/kubeadm-config-print-join-defaults.1
docs/man/man1/kubeadm-config-print.1
docs/man/man1/kubeadm-config-upload-from-file.1
docs/man/man1/kubeadm-config-upload-from-flags.1
docs/man/man1/kubeadm-config-upload.1

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.