forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
unlink_secret_from_object.go
121 lines (100 loc) · 3.48 KB
/
unlink_secret_from_object.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package secrets
import (
"errors"
"fmt"
"io"
kapi "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra"
)
const UnlinkSecretRecommendedName = "unlink"
var (
unlinkSecretLong = templates.LongDesc(`
Unlink (detach) secrets from a service account
If a secret is no longer valid for a pod, build or image pull, you may unlink it from a service account.`)
unlinkSecretExample = templates.Examples(`
# Unlink a secret currently associated with a service account:
%[1]s serviceaccount-name secret-name another-secret-name ...`)
)
type UnlinkSecretOptions struct {
SecretOptions
}
// NewCmdUnlinkSecret creates a command object for detaching one or more secret references from a service account
func NewCmdUnlinkSecret(name, fullName string, f kcmdutil.Factory, out io.Writer) *cobra.Command {
o := &UnlinkSecretOptions{SecretOptions{Out: out}}
cmd := &cobra.Command{
Use: fmt.Sprintf("%s serviceaccount-name secret-name [another-secret-name] ...", name),
Short: "Detach secrets from a ServiceAccount",
Long: unlinkSecretLong,
Example: fmt.Sprintf(unlinkSecretExample, fullName),
Run: func(c *cobra.Command, args []string) {
if err := o.Complete(f, args); err != nil {
kcmdutil.CheckErr(kcmdutil.UsageErrorf(c, err.Error()))
}
if err := o.Validate(); err != nil {
kcmdutil.CheckErr(kcmdutil.UsageErrorf(c, err.Error()))
}
if err := o.UnlinkSecrets(); err != nil {
kcmdutil.CheckErr(err)
}
},
}
return cmd
}
func (o UnlinkSecretOptions) UnlinkSecrets() error {
serviceaccount, err := o.GetServiceAccount()
if err != nil {
return err
}
if err = o.unlinkSecretsFromServiceAccount(serviceaccount); err != nil {
return err
}
return nil
}
// unlinkSecretsFromServiceAccount detaches pull and mount secrets from the service account.
func (o UnlinkSecretOptions) unlinkSecretsFromServiceAccount(serviceaccount *kapi.ServiceAccount) error {
// All of the requested secrets must be present in either the Mount or Pull secrets
// If any of them are not present, we'll return an error and push no changes.
rmSecrets, hasNotFound, err := o.GetSecrets(true)
if err != nil {
return err
}
rmSecretNames := o.GetSecretNames(rmSecrets)
newMountSecrets := []kapi.ObjectReference{}
newPullSecrets := []kapi.LocalObjectReference{}
updated := false
// Check the mount secrets
for _, secret := range serviceaccount.Secrets {
if !rmSecretNames.Has(secret.Name) {
// Copy this back in, since it doesn't match the ones we're removing
newMountSecrets = append(newMountSecrets, secret)
} else {
updated = true
}
}
// Check the image pull secrets
for _, imagePullSecret := range serviceaccount.ImagePullSecrets {
if !rmSecretNames.Has(imagePullSecret.Name) {
// Copy this back in, since it doesn't match the one we're removing
newPullSecrets = append(newPullSecrets, imagePullSecret)
} else {
updated = true
}
}
if updated {
// Save the updated Secret lists back to the server
serviceaccount.Secrets = newMountSecrets
serviceaccount.ImagePullSecrets = newPullSecrets
_, err = o.KubeCoreClient.ServiceAccounts(o.Namespace).Update(serviceaccount)
if err != nil {
return err
}
if hasNotFound {
return fmt.Errorf("Unlinked deleted secrets from %s/%s service account", o.Namespace, serviceaccount.Name)
}
return nil
} else {
return errors.New("No valid secrets found or secrets not linked to service account")
}
}