forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deleted_token_secrets.go
120 lines (102 loc) · 3.82 KB
/
deleted_token_secrets.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
package controllers
import (
"time"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
apierrors "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/client/cache"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/controller/framework"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/runtime"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/watch"
)
// DockercfgTokenDeletedControllerOptions contains options for the DockercfgTokenDeletedController
type DockercfgTokenDeletedControllerOptions struct {
// Resync is the time.Duration at which to fully re-list secrets.
// If zero, re-list will be delayed as long as possible
Resync time.Duration
}
// NewDockercfgTokenDeletedController returns a new *DockercfgTokenDeletedController.
func NewDockercfgTokenDeletedController(cl client.Interface, options DockercfgTokenDeletedControllerOptions) *DockercfgTokenDeletedController {
e := &DockercfgTokenDeletedController{
client: cl,
}
dockercfgSelector := fields.OneTermEqualSelector(api.SecretTypeField, string(api.SecretTypeServiceAccountToken))
_, e.secretController = framework.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
opts := api.ListOptions{FieldSelector: dockercfgSelector}
return e.client.Secrets(api.NamespaceAll).List(opts)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
opts := api.ListOptions{FieldSelector: dockercfgSelector, ResourceVersion: options.ResourceVersion}
return e.client.Secrets(api.NamespaceAll).Watch(opts)
},
},
&api.Secret{},
options.Resync,
framework.ResourceEventHandlerFuncs{
DeleteFunc: e.secretDeleted,
},
)
return e
}
// The DockercfgTokenDeletedController watches for service account tokens to be deleted.
// On delete, it removes the associated dockercfg secret if it exists.
type DockercfgTokenDeletedController struct {
stopChan chan struct{}
client client.Interface
secretController *framework.Controller
}
// Runs controller loops and returns immediately
func (e *DockercfgTokenDeletedController) Run() {
if e.stopChan == nil {
e.stopChan = make(chan struct{})
go e.secretController.Run(e.stopChan)
}
}
// Stop gracefully shuts down this controller
func (e *DockercfgTokenDeletedController) Stop() {
if e.stopChan != nil {
close(e.stopChan)
e.stopChan = nil
}
}
// secretDeleted reacts to a token secret being deleted by looking for a corresponding dockercfg secret and deleting it if it exists
func (e *DockercfgTokenDeletedController) secretDeleted(obj interface{}) {
tokenSecret, ok := obj.(*api.Secret)
if !ok {
return
}
dockercfgSecrets, err := e.findDockercfgSecrets(tokenSecret)
if err != nil {
glog.Error(err)
return
}
if len(dockercfgSecrets) == 0 {
return
}
// remove the reference token secrets
for _, dockercfgSecret := range dockercfgSecrets {
if err := e.client.Secrets(dockercfgSecret.Namespace).Delete(dockercfgSecret.Name); (err != nil) && !apierrors.IsNotFound(err) {
utilruntime.HandleError(err)
}
}
}
// findDockercfgSecret checks all the secrets in the namespace to see if the token secret has any existing dockercfg secrets that reference it
func (e *DockercfgTokenDeletedController) findDockercfgSecrets(tokenSecret *api.Secret) ([]*api.Secret, error) {
dockercfgSecrets := []*api.Secret{}
options := api.ListOptions{FieldSelector: fields.OneTermEqualSelector(api.SecretTypeField, string(api.SecretTypeDockercfg))}
potentialSecrets, err := e.client.Secrets(tokenSecret.Namespace).List(options)
if err != nil {
return nil, err
}
for i, currSecret := range potentialSecrets.Items {
if currSecret.Annotations[ServiceAccountTokenSecretNameKey] == tokenSecret.Name {
dockercfgSecrets = append(dockercfgSecrets, &potentialSecrets.Items[i])
}
}
return dockercfgSecrets, nil
}