Skip to content

Commit dd97fd1

Browse files
Merge pull request #28 from itdove/revoke_token
Revoke token
2 parents 489d7e8 + 4853374 commit dd97fd1

File tree

11 files changed

+263
-33
lines changed

11 files changed

+263
-33
lines changed

CHANGELOG.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
[comment]: # ( Copyright Contributors to the Open Cluster Management project )
22
# Release Content
3+
## Additions
4+
- Add `clusteradm delete token` [Create cmd to revoke the bootstrap token](https://github.com/open-cluster-management-io/clusteradm/issues/23)
35

4-
- Add support for non-bootstrap token enabled environment [issue 16](https://github.com/open-cluster-management-io/clusteradm/issues/16)
5-
- Avoid to run the `clusteradm init` twice on the hub [issue 21](https://github.com/open-cluster-management-io/clusteradm/issues/21)
6-
- Add command `clusteradm get token` [issue 22](https://github.com/open-cluster-management-io/clusteradm/issues/22)
6+
## Breaking Changes
7+
8+
## Changes
9+
10+
## Bug Fixes

VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.1.0-alpha.3
1+
0.1.0-alpha.4

build/run-functional-tests.sh

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function joinscenario() {
6969
CMDJOINRESULT=$(join_hub "${CMDINITRESULT}" $1)
7070
echo "join command result: "$CMDJOINRESULT >&2
7171

72-
echo "Wait 4 min to stabilize" >&2
72+
echo "Wait 4 min maximum to stabilize" >&2
7373

7474
kubectl config use-context kind-${CLUSTER_NAME}-hub
7575
CMDACCEPTRESULT=$(accept_cluster "${CMDJOINRESULT}")
@@ -85,17 +85,18 @@ function joinscenario() {
8585

8686
function gettokenscenario() {
8787
echo "gettokenscenario 1st parameter: "$1 >&2
88+
echo "gettokenscenario 2nd parameter: "$2 >&2
8889
echo "get token from hub" >&2
8990
kubectl config use-context kind-${CLUSTER_NAME}-hub
90-
CMGETTOKENRESULT=$(gettoken)
91+
CMGETTOKENRESULT=$(gettoken $2)
9192
echo "get token command result: "$CMGETTOKENRESULT >&2
9293

9394
echo "join hub" >&2
9495
kubectl config use-context kind-${CLUSTER_NAME}-$1
9596
CMDJOINRESULT=$(join_hub "${CMGETTOKENRESULT}" $1)
9697
echo "join command result: "$CMDJOINRESULT >&1
9798

98-
echo "Wait 4 min to stabilize" >&2
99+
echo "Wait 4 min maximum to stabilize" >&2
99100

100101
kubectl config use-context kind-${CLUSTER_NAME}-hub
101102
CMDACCEPTRESULT=$(accept_cluster "${CMDJOINRESULT}")
@@ -107,6 +108,22 @@ function gettokenscenario() {
107108
else
108109
echo "accept command result: "$CMDACCEPTRESULT >&2
109110
fi
111+
112+
echo "delete token" >&2
113+
clusteradm delete token
114+
if [ $? != 0 ]
115+
then
116+
echo "accept command result: "$CMDACCEPTRESULT >&2
117+
ERROR_REPORT=$ERROR_REPORT+"no CSR get approved\n"
118+
fi
119+
120+
echo "get token from hub" >&2
121+
kubectl config use-context kind-${CLUSTER_NAME}-hub
122+
CMGETTOKENRESULT2=$(gettoken $2)
123+
if [ "$CMGETTOKENRESULT" == "$CMGETTOKENRESULT2" ]
124+
then
125+
ERROR_REPORT=$ERROR_REPORT+"new token identical as previous token after delete"
126+
fi
110127
}
111128

112129
echo "With bootstrap token"
@@ -132,7 +149,7 @@ kind delete cluster --name ${CLUSTER_NAME}-c1
132149
kind create cluster --name ${CLUSTER_NAME}-c2
133150
echo "Joining with get token and bootstrap token"
134151
echo "------------------------------------------"
135-
gettokenscenario c2
152+
gettokenscenario c2 --use-bootstrap-token
136153

137154
kind delete cluster --name ${CLUSTER_NAME}-hub
138155
kind delete cluster --name ${CLUSTER_NAME}-c2

cmd/clusteradm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"open-cluster-management.io/clusteradm/pkg/cmd/version"
1919

2020
acceptclusters "open-cluster-management.io/clusteradm/pkg/cmd/accept"
21+
deletecmd "open-cluster-management.io/clusteradm/pkg/cmd/delete"
2122
"open-cluster-management.io/clusteradm/pkg/cmd/get"
2223
inithub "open-cluster-management.io/clusteradm/pkg/cmd/init"
2324
joinhub "open-cluster-management.io/clusteradm/pkg/cmd/join"
@@ -65,6 +66,7 @@ func main() {
6566
Message: "Registration commands:",
6667
Commands: []*cobra.Command{
6768
get.NewCmd(clusteradmFlags, streams),
69+
deletecmd.NewCmd(clusteradmFlags, streams),
6870
inithub.NewCmd(clusteradmFlags, streams),
6971
joinhub.NewCmd(clusteradmFlags, streams),
7072
acceptclusters.NewCmd(clusteradmFlags, streams),

pkg/cmd/delete/cmd.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright Contributors to the Open Cluster Management project
2+
package get
3+
4+
import (
5+
"github.com/spf13/cobra"
6+
"k8s.io/cli-runtime/pkg/genericclioptions"
7+
"open-cluster-management.io/clusteradm/pkg/cmd/delete/token"
8+
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
9+
)
10+
11+
// NewCmd provides a cobra command wrapping NewCmdImportCluster
12+
func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *cobra.Command {
13+
cmd := &cobra.Command{
14+
Use: "delete",
15+
Short: "delete a resource",
16+
}
17+
18+
cmd.AddCommand(token.NewCmd(clusteradmFlags, streams))
19+
20+
return cmd
21+
}

pkg/cmd/delete/token/cmd.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright Contributors to the Open Cluster Management project
2+
package token
3+
4+
import (
5+
"fmt"
6+
7+
"open-cluster-management.io/clusteradm/pkg/helpers"
8+
9+
"github.com/spf13/cobra"
10+
"k8s.io/cli-runtime/pkg/genericclioptions"
11+
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
12+
)
13+
14+
var example = `
15+
# Get the bootstrap token
16+
%[1]s get token
17+
`
18+
19+
// NewCmd ...
20+
func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *cobra.Command {
21+
o := newOptions(clusteradmFlags, streams)
22+
23+
cmd := &cobra.Command{
24+
Use: "token",
25+
Short: "get the bootsrap token",
26+
Example: fmt.Sprintf(example, helpers.GetExampleHeader()),
27+
SilenceUsage: true,
28+
PreRun: func(c *cobra.Command, args []string) {
29+
helpers.DryRunMessage(o.ClusteradmFlags.DryRun)
30+
},
31+
RunE: func(c *cobra.Command, args []string) error {
32+
if err := o.complete(c, args); err != nil {
33+
return err
34+
}
35+
if err := o.validate(); err != nil {
36+
return err
37+
}
38+
if err := o.run(); err != nil {
39+
return err
40+
}
41+
42+
return nil
43+
},
44+
}
45+
46+
return cmd
47+
}

pkg/cmd/delete/token/exec.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright Contributors to the Open Cluster Management project
2+
package token
3+
4+
import (
5+
"context"
6+
"fmt"
7+
8+
"k8s.io/apimachinery/pkg/api/errors"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
11+
"open-cluster-management.io/clusteradm/pkg/config"
12+
"open-cluster-management.io/clusteradm/pkg/helpers"
13+
14+
"github.com/spf13/cobra"
15+
16+
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
17+
"k8s.io/client-go/kubernetes"
18+
)
19+
20+
func (o *Options) complete(cmd *cobra.Command, args []string) (err error) {
21+
return nil
22+
}
23+
24+
func (o *Options) validate() error {
25+
restConfig, err := o.ClusteradmFlags.KubectlFactory.ToRESTConfig()
26+
if err != nil {
27+
return err
28+
}
29+
30+
apiExtensionsClient, err := apiextensionsclient.NewForConfig(restConfig)
31+
if err != nil {
32+
return err
33+
}
34+
installed, err := helpers.IsClusterManagerInstalled(apiExtensionsClient)
35+
if err != nil {
36+
return err
37+
}
38+
if !installed {
39+
return fmt.Errorf("this is not a hub")
40+
}
41+
return err
42+
}
43+
44+
func (o *Options) run() error {
45+
46+
kubeClient, err := o.ClusteradmFlags.KubectlFactory.KubernetesClientSet()
47+
if err != nil {
48+
return err
49+
}
50+
51+
if o.ClusteradmFlags.DryRun {
52+
return nil
53+
}
54+
55+
return o.deleteToken(kubeClient)
56+
}
57+
58+
func (o *Options) deleteToken(kubeClient *kubernetes.Clientset) error {
59+
//Delete bootstrap token bindings
60+
err := kubeClient.RbacV1().ClusterRoleBindings().Delete(context.TODO(), config.BootstrapClusterRoleBindingName, metav1.DeleteOptions{})
61+
if err != nil && !errors.IsNotFound(err) {
62+
return err
63+
}
64+
err = kubeClient.RbacV1().ClusterRoleBindings().Delete(context.TODO(), config.BootstrapClusterRoleBindingSAName, metav1.DeleteOptions{})
65+
if err != nil && !errors.IsNotFound(err) {
66+
return err
67+
}
68+
69+
//Delete Roles
70+
err = kubeClient.RbacV1().ClusterRoles().Delete(context.TODO(), config.BootstrapClusterRoleName, metav1.DeleteOptions{})
71+
if err != nil && !errors.IsNotFound(err) {
72+
return err
73+
}
74+
75+
//Detele bootstrap token secret
76+
secret, err := helpers.GetBootstrapSecret(kubeClient)
77+
if err == nil {
78+
err = kubeClient.CoreV1().Secrets(secret.Namespace).Delete(context.TODO(), secret.Name, metav1.DeleteOptions{})
79+
if err != nil && !errors.IsNotFound(err) {
80+
return err
81+
}
82+
}
83+
if err != nil && !errors.IsNotFound(err) {
84+
return err
85+
}
86+
//Delete service account
87+
err = kubeClient.CoreV1().ServiceAccounts(config.OpenClusterManagementNamespace).Delete(context.TODO(), config.BootstrapSAName, metav1.DeleteOptions{})
88+
if err != nil && !errors.IsNotFound(err) {
89+
return err
90+
}
91+
//No need to delete the secret containing the token
92+
//as it will be automatically deleted because the SA is deleted
93+
return nil
94+
}

pkg/cmd/delete/token/options.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright Contributors to the Open Cluster Management project
2+
package token
3+
4+
import (
5+
"k8s.io/cli-runtime/pkg/genericclioptions"
6+
genericclioptionsclusteradm "open-cluster-management.io/clusteradm/pkg/genericclioptions"
7+
)
8+
9+
//Options: The structure holding all the command-line options
10+
type Options struct {
11+
//ClusteradmFlags: The generic optiosn from the clusteradm cli-runtime.
12+
ClusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags
13+
}
14+
15+
func newOptions(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, streams genericclioptions.IOStreams) *Options {
16+
return &Options{
17+
ClusteradmFlags: clusteradmFlags,
18+
}
19+
}

pkg/cmd/init/scenario/init/bootstrap_sa_cluster_role_binding.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
apiVersion: rbac.authorization.k8s.io/v1
33
kind: ClusterRoleBinding
44
metadata:
5-
name: cluster-bootstrap
5+
name: cluster-bootstrap-sa
66
roleRef:
77
apiGroup: rbac.authorization.k8s.io
88
kind: ClusterRole

pkg/config/env.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
package config
44

55
const (
6-
OpenClusterManagementNamespace = "open-cluster-management"
7-
BootstrapSAName = "cluster-bootstrap"
8-
ClusterManagerName = "cluster-manager"
9-
LabelApp = "app"
10-
BootstrapSecretPrefix = "bootstrap-token-"
6+
OpenClusterManagementNamespace = "open-cluster-management"
7+
BootstrapSAName = "cluster-bootstrap"
8+
BootstrapClusterRoleBindingName = "cluster-bootstrap"
9+
BootstrapClusterRoleBindingSAName = "cluster-bootstrap-sa"
10+
BootstrapClusterRoleName = "system:open-cluster-management:bootstrap"
11+
ClusterManagerName = "cluster-manager"
12+
LabelApp = "app"
13+
BootstrapSecretPrefix = "bootstrap-token-"
1114
)

0 commit comments

Comments
 (0)