forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdeleted_token_secrets.go
118 lines (100 loc) · 3.79 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
package controllers
import (
"fmt"
"time"
"github.com/golang/glog"
"k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
informers "k8s.io/client-go/informers/core/v1"
kclientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/apis/core"
)
// 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(secrets informers.SecretInformer, cl kclientset.Interface, options DockercfgTokenDeletedControllerOptions) *DockercfgTokenDeletedController {
e := &DockercfgTokenDeletedController{
client: cl,
}
e.secretController = secrets.Informer().GetController()
secrets.Informer().AddEventHandlerWithResyncPeriod(
cache.FilteringResourceEventHandler{
FilterFunc: func(obj interface{}) bool {
switch t := obj.(type) {
case *v1.Secret:
return t.Type == v1.SecretTypeServiceAccountToken
default:
utilruntime.HandleError(fmt.Errorf("object passed to %T that is not expected: %T", e, obj))
return false
}
},
Handler: cache.ResourceEventHandlerFuncs{
DeleteFunc: e.secretDeleted,
},
},
options.Resync,
)
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 {
client kclientset.Interface
secretController cache.Controller
}
// Runs controller loops and returns on shutdown
func (e *DockercfgTokenDeletedController) Run(stopCh <-chan struct{}) {
defer utilruntime.HandleCrash()
glog.Infof("Starting DockercfgTokenDeletedController controller")
defer glog.Infof("Shutting down DockercfgTokenDeletedController controller")
// Wait for the stores to fill
if !cache.WaitForCacheSync(stopCh, e.secretController.HasSynced) {
return
}
glog.V(1).Infof("caches synced")
<-stopCh
}
// 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.(*v1.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.Core().Secrets(dockercfgSecret.Namespace).Delete(dockercfgSecret.Name, nil); (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 *v1.Secret) ([]*v1.Secret, error) {
dockercfgSecrets := []*v1.Secret{}
options := metav1.ListOptions{FieldSelector: fields.OneTermEqualSelector(api.SecretTypeField, string(v1.SecretTypeDockercfg)).String()}
potentialSecrets, err := e.client.Core().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
}