Skip to content

Commit 1156193

Browse files
committed
delete secret
Signed-off-by: Dominique Vernier <[email protected]>
1 parent 489d7e8 commit 1156193

File tree

8 files changed

+223
-20
lines changed

8 files changed

+223
-20
lines changed

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: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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 && !errors.IsNotFound(err) {
78+
return err
79+
}
80+
err = kubeClient.CoreV1().Secrets(secret.Namespace).Delete(context.TODO(), secret.Name, metav1.DeleteOptions{})
81+
if err != nil && !errors.IsNotFound(err) {
82+
return err
83+
}
84+
//Delete service account
85+
err = kubeClient.CoreV1().ServiceAccounts(config.OpenClusterManagementNamespace).Delete(context.TODO(), config.BootstrapSAName, metav1.DeleteOptions{})
86+
if err != nil && !errors.IsNotFound(err) {
87+
return err
88+
}
89+
//No need to delete the secret containing the token
90+
//as it will be automatically deleted because the SA is deleted
91+
return nil
92+
}

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
)

pkg/helpers/client.go

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,37 +115,46 @@ func GetToken(kubeClient kubernetes.Interface) (string, TokenType, error) {
115115
return token, ServiceAccountToken, nil
116116
}
117117

118-
//GetBootstrapToken returns the service-account token in kube-system
119-
func GetBootstrapToken(kubeClient kubernetes.Interface) (string, error) {
118+
//GetBootstrapSecret returns the secret in kube-system
119+
func GetBootstrapSecret(kubeClient kubernetes.Interface) (*corev1.Secret, error) {
120120
var bootstrapSecret *corev1.Secret
121121
l, err := kubeClient.CoreV1().
122122
Secrets("kube-system").
123123
List(context.TODO(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%v = %v", config.LabelApp, config.ClusterManagerName)})
124124
if err != nil {
125-
return "", err
125+
return nil, err
126126
}
127127
for _, s := range l.Items {
128128
if strings.HasPrefix(s.Name, config.BootstrapSecretPrefix) {
129129
bootstrapSecret = &s
130130
}
131131
}
132-
if bootstrapSecret != nil {
133-
return fmt.Sprintf("%s.%s", string(bootstrapSecret.Data["token-id"]), string(bootstrapSecret.Data["token-secret"])), nil
132+
if bootstrapSecret == nil {
133+
return nil, errors.NewNotFound(schema.GroupResource{
134+
Group: corev1.GroupName,
135+
Resource: "secrets"},
136+
fmt.Sprintf("%s*", config.BootstrapSecretPrefix))
137+
134138
}
135-
return "", errors.NewNotFound(schema.GroupResource{
136-
Group: corev1.GroupName,
137-
Resource: "secrets"},
138-
fmt.Sprintf("%s*", config.BootstrapSecretPrefix))
139+
return bootstrapSecret, err
139140
}
140141

141-
//GetBootstrapSecretFromSA retrieves the service-account token secret
142-
func GetBootstrapTokenFromSA(
143-
kubeClient kubernetes.Interface) (string, error) {
142+
//GetBootstrapToken returns the token in kube-system
143+
func GetBootstrapToken(kubeClient kubernetes.Interface) (string, error) {
144+
bootstrapSecret, err := GetBootstrapSecret(kubeClient)
145+
if err != nil {
146+
return "", err
147+
}
148+
return fmt.Sprintf("%s.%s", string(bootstrapSecret.Data["token-id"]), string(bootstrapSecret.Data["token-secret"])), nil
149+
}
150+
151+
func GetBootstrapSecretFromSA(
152+
kubeClient kubernetes.Interface) (*corev1.Secret, error) {
144153
sa, err := kubeClient.CoreV1().
145154
ServiceAccounts(config.OpenClusterManagementNamespace).
146155
Get(context.TODO(), config.BootstrapSAName, metav1.GetOptions{})
147156
if err != nil {
148-
return "", err
157+
return nil, err
149158
}
150159
var secret *corev1.Secret
151160
for _, objectRef := range sa.Secrets {
@@ -169,12 +178,22 @@ func GetBootstrapTokenFromSA(
169178
}
170179
}
171180
if secret == nil {
172-
return "", fmt.Errorf("secret with prefix %s and type %s not found in service account %s/%s",
181+
return nil, fmt.Errorf("secret with prefix %s and type %s not found in service account %s/%s",
173182
config.BootstrapSAName,
174183
corev1.SecretTypeServiceAccountToken,
175184
config.OpenClusterManagementNamespace,
176185
config.BootstrapSAName)
177186
}
187+
return secret, nil
188+
}
189+
190+
//GetBootstrapSecretFromSA retrieves the service-account token secret
191+
func GetBootstrapTokenFromSA(
192+
kubeClient kubernetes.Interface) (string, error) {
193+
secret, err := GetBootstrapSecretFromSA(kubeClient)
194+
if err != nil {
195+
return "", err
196+
}
178197
return string(secret.Data["token"]), nil
179198
}
180199

0 commit comments

Comments
 (0)