diff --git a/cmd/kubeadm/app/cmd/token.go b/cmd/kubeadm/app/cmd/token.go index ec95277b51f..62b1bbe317a 100644 --- a/cmd/kubeadm/app/cmd/token.go +++ b/cmd/kubeadm/app/cmd/token.go @@ -158,11 +158,11 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command { tokenCmd.AddCommand(listCmd) deleteCmd := &cobra.Command{ - Use: "delete [token-value]", + Use: "delete [token-value] ...", DisableFlagsInUseLine: true, Short: "Delete bootstrap tokens on the server.", Long: dedent.Dedent(` - This command will delete a given bootstrap token for you. + This command will delete a list of bootstrap tokens for you. The [token-value] is the full Token of the form "[a-z0-9]{6}.[a-z0-9]{16}" or the Token ID of the form "[a-z0-9]{6}" to delete. @@ -175,7 +175,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command { client, err := getClientset(kubeConfigFile, dryRun) kubeadmutil.CheckErr(err) - err = RunDeleteToken(out, client, args[0]) + err = RunDeleteTokens(out, client, args) kubeadmutil.CheckErr(err) }, } @@ -296,27 +296,29 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er return nil } -// RunDeleteToken removes a bootstrap token from the server. -func RunDeleteToken(out io.Writer, client clientset.Interface, tokenIDOrToken string) error { - // Assume the given first argument is a token id and try to parse it - tokenID := tokenIDOrToken - klog.V(1).Infoln("[token] parsing token ID") - if !bootstraputil.IsValidBootstrapTokenID(tokenIDOrToken) { - // Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only - bts, err := kubeadmapiv1beta1.NewBootstrapTokenString(tokenIDOrToken) - if err != nil { - return errors.Errorf("given token or token id %q didn't match pattern %q or %q", - tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern) +// RunDeleteTokens removes a bootstrap tokens from the server. +func RunDeleteTokens(out io.Writer, client clientset.Interface, tokenIDsOrTokens []string) error { + for _, tokenIDOrToken := range tokenIDsOrTokens { + // Assume this is a token id and try to parse it + tokenID := tokenIDOrToken + klog.V(1).Infof("[token] parsing token %q", tokenIDOrToken) + if !bootstraputil.IsValidBootstrapTokenID(tokenIDOrToken) { + // Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only + bts, err := kubeadmapiv1beta1.NewBootstrapTokenString(tokenIDOrToken) + if err != nil { + return errors.Errorf("given token %q didn't match pattern %q or %q", + tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern) + } + tokenID = bts.ID } - tokenID = bts.ID - } - tokenSecretName := bootstraputil.BootstrapTokenSecretName(tokenID) - klog.V(1).Infoln("[token] deleting token") - if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(tokenSecretName, nil); err != nil { - return errors.Wrap(err, "failed to delete bootstrap token") + tokenSecretName := bootstraputil.BootstrapTokenSecretName(tokenID) + klog.V(1).Infof("[token] deleting token %q", tokenID) + if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(tokenSecretName, nil); err != nil { + return errors.Wrapf(err, "failed to delete bootstrap token %q", tokenID) + } + fmt.Fprintf(out, "bootstrap token %q deleted\n", tokenID) } - fmt.Fprintf(out, "bootstrap token with id %q deleted\n", tokenID) return nil } diff --git a/cmd/kubeadm/app/cmd/token_test.go b/cmd/kubeadm/app/cmd/token_test.go index 3d6837748ce..77c33467975 100644 --- a/cmd/kubeadm/app/cmd/token_test.go +++ b/cmd/kubeadm/app/cmd/token_test.go @@ -300,7 +300,7 @@ func TestGetClientset(t *testing.T) { } } -func TestRunDeleteToken(t *testing.T) { +func TestRunDeleteTokens(t *testing.T) { var buf bytes.Buffer tmpDir, err := ioutil.TempDir("", "kubeadm-token-test") @@ -327,12 +327,12 @@ func TestRunDeleteToken(t *testing.T) { // test valid; should not fail // for some reason Secrets().Delete() does not fail even for this dummy config - if err = RunDeleteToken(&buf, client, "abcdef.1234567890123456"); err != nil { + if err = RunDeleteTokens(&buf, client, []string{"abcdef.1234567890123456", "abcdef.2345678901234567"}); err != nil { t.Errorf("RunDeleteToken() failed for a valid token: %v", err) } // test invalid token; should fail - if err = RunDeleteToken(&buf, client, "invalid-token"); err == nil { + if err = RunDeleteTokens(&buf, client, []string{"invalid-token"}); err == nil { t.Errorf("RunDeleteToken() succeeded for an invalid token: %v", err) } }