-
Notifications
You must be signed in to change notification settings - Fork 590
/
secret_controller.go
141 lines (118 loc) · 4.48 KB
/
secret_controller.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package configuration
import (
"context"
"time"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
"github.com/kong/kubernetes-ingress-controller/v3/internal/controllers"
ctrlref "github.com/kong/kubernetes-ingress-controller/v3/internal/controllers/reference"
"github.com/kong/kubernetes-ingress-controller/v3/internal/util"
)
// -----------------------------------------------------------------------------
// CoreV1 Secret - Reconciler
// -----------------------------------------------------------------------------
const (
CACertLabelKey = "konghq.com/ca-cert"
)
// CoreV1SecretReconciler reconciles Secret resources.
type CoreV1SecretReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
DataplaneClient controllers.DataPlane
CacheSyncTimeout time.Duration
ReferenceIndexers ctrlref.CacheIndexers
}
var _ controllers.Reconciler = &CoreV1SecretReconciler{}
// SetupWithManager sets up the controller with the Manager.
func (r *CoreV1SecretReconciler) SetupWithManager(mgr ctrl.Manager) error {
c, err := controller.New("CoreV1Secret", mgr, controller.Options{
Reconciler: r,
LogConstructor: func(_ *reconcile.Request) logr.Logger {
return r.Log
},
CacheSyncTimeout: r.CacheSyncTimeout,
})
if err != nil {
return err
}
predicateFuncs := predicate.NewPredicateFuncs(r.shouldReconcileSecret)
// we should always try to delete secrets in caches when they are deleted in cluster.
predicateFuncs.DeleteFunc = func(event event.DeleteEvent) bool { return true }
return c.Watch(
source.Kind(mgr.GetCache(), &corev1.Secret{}),
&handler.EnqueueRequestForObject{},
predicateFuncs,
)
}
// SetLogger sets the logger.
func (r *CoreV1SecretReconciler) SetLogger(l logr.Logger) {
r.Log = l
}
// shouldReconcileSecret is the filter function to judge whether the secret should be reconciled
// and stored in cache of the controller. It returns true for the secret should be reconciled when:
// - the secret has label: konghq.com/ca-cert:true
// - or the secret is referred by objects we care (service, ingress, gateway, ...)
func (r *CoreV1SecretReconciler) shouldReconcileSecret(obj client.Object) bool {
secret, ok := obj.(*corev1.Secret)
if !ok {
return false
}
labels := secret.Labels
if labels != nil && labels[CACertLabelKey] == "true" {
return true
}
referred, err := r.ReferenceIndexers.ObjectReferred(secret)
if err != nil {
r.Log.Error(err, "Failed to check whether secret referred",
"namespace", secret.Namespace, "name", secret.Name)
return false
}
return referred
}
// +kubebuilder:rbac:groups="",resources=secrets,verbs=list;watch
// Reconcile processes the watched objects.
func (r *CoreV1SecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := r.Log.WithValues("CoreV1Secret", req.NamespacedName)
// get the relevant object
secret := new(corev1.Secret)
if err := r.Get(ctx, req.NamespacedName, secret); err != nil {
if apierrors.IsNotFound(err) {
secret.Namespace = req.Namespace
secret.Name = req.Name
return ctrl.Result{}, r.DataplaneClient.DeleteObject(secret)
}
return ctrl.Result{}, err
}
log.V(util.DebugLevel).Info("Reconciling resource", "namespace", req.Namespace, "name", req.Name)
// clean the object up if it's being deleted
if !secret.DeletionTimestamp.IsZero() && time.Now().After(secret.DeletionTimestamp.Time) {
log.V(util.DebugLevel).Info("Resource is being deleted, its configuration will be removed", "type", "Secret", "namespace", req.Namespace, "name", req.Name)
objectExistsInCache, err := r.DataplaneClient.ObjectExists(secret)
if err != nil {
return ctrl.Result{}, err
}
if objectExistsInCache {
if err := r.DataplaneClient.DeleteObject(secret); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{Requeue: true}, nil // wait until the object is no longer present in the cache
}
return ctrl.Result{}, nil
}
// update the kong Admin API with the changes
if err := r.DataplaneClient.UpdateObject(secret); err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}