mirror of https://github.com/k3s-io/k3s
Merge pull request #69617 from rosti/config-defaults-split
kubeadm: Introduce config print init/join-defaultspull/58/head
commit
a6e273214b
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
Loading…
Reference in New Issue