diff --git a/cmd/kubeadm/app/cmd/token.go b/cmd/kubeadm/app/cmd/token.go index 84d3b874100..56abbf25ee2 100644 --- a/cmd/kubeadm/app/cmd/token.go +++ b/cmd/kubeadm/app/cmd/token.go @@ -98,6 +98,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command { var cfgPath string var printJoinCommand bool + var certificateKey string bto := options.NewBootstrapTokenOptions() createCmd := &cobra.Command{ @@ -132,13 +133,15 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command { return err } - return RunCreateToken(out, client, cfgPath, cfg, printJoinCommand, kubeConfigFile) + return RunCreateToken(out, client, cfgPath, cfg, printJoinCommand, certificateKey, kubeConfigFile) }, } options.AddConfigFlag(createCmd.Flags(), &cfgPath) createCmd.Flags().BoolVar(&printJoinCommand, "print-join-command", false, "Instead of printing only the token, print the full 'kubeadm join' flag needed to join the cluster using the token.") + createCmd.Flags().StringVar(&certificateKey, + options.CertificateKey, "", "When used together with '--print-join-command', print the full 'kubeadm join' flag needed to join the cluster as a control-plane. To create a new certificate key you must use 'kubeadm init phase upload-certs --upload-certs'.") bto.AddTTLFlagWithName(createCmd.Flags(), "ttl") bto.AddUsagesFlag(createCmd.Flags()) bto.AddGroupsFlag(createCmd.Flags()) @@ -226,7 +229,7 @@ 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, initCfg *kubeadmapiv1beta2.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error { +func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, initCfg *kubeadmapiv1beta2.InitConfiguration, printJoinCommand bool, certificateKey string, 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 @@ -257,14 +260,28 @@ func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, i // otherwise, just print the token if printJoinCommand { skipTokenPrint := false - joinCommand, err := cmdutil.GetJoinWorkerCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), skipTokenPrint) - if err != nil { - return errors.Wrap(err, "failed to get join command") + if certificateKey != "" { + skipCertificateKeyPrint := false + joinCommand, err := cmdutil.GetJoinControlPlaneCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), certificateKey, skipTokenPrint, skipCertificateKeyPrint) + if err != nil { + return errors.Wrap(err, "failed to get join command") + } + joinCommand = strings.ReplaceAll(joinCommand, "\\\n", "") + joinCommand = strings.ReplaceAll(joinCommand, "\t", "") + fmt.Fprintln(out, joinCommand) + } else { + joinCommand, err := cmdutil.GetJoinWorkerCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), skipTokenPrint) + if err != nil { + return errors.Wrap(err, "failed to get join command") + } + joinCommand = strings.ReplaceAll(joinCommand, "\\\n", "") + joinCommand = strings.ReplaceAll(joinCommand, "\t", "") + fmt.Fprintln(out, joinCommand) } - joinCommand = strings.ReplaceAll(joinCommand, "\\\n", "") - joinCommand = strings.ReplaceAll(joinCommand, "\t", "") - fmt.Fprintln(out, joinCommand) } else { + if certificateKey != "" { + return errors.Wrap(err, "cannot use --certificate-key without --print-join-command") + } fmt.Fprintln(out, internalcfg.BootstrapTokens[0].Token.String()) } diff --git a/cmd/kubeadm/app/cmd/token_test.go b/cmd/kubeadm/app/cmd/token_test.go index a86bf6f8d6d..bbe09c54ea2 100644 --- a/cmd/kubeadm/app/cmd/token_test.go +++ b/cmd/kubeadm/app/cmd/token_test.go @@ -172,7 +172,7 @@ func TestRunCreateToken(t *testing.T) { }, } - err = RunCreateToken(&buf, fakeClient, "", cfg, tc.printJoin, "") + err = RunCreateToken(&buf, fakeClient, "", cfg, tc.printJoin, "", "") if tc.expectedError && err == nil { t.Error("unexpected success") } else if !tc.expectedError && err != nil {