-
Notifications
You must be signed in to change notification settings - Fork 14
/
base_reconciler.go
117 lines (95 loc) · 3.21 KB
/
base_reconciler.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
package reconcilers
import (
"context"
"fmt"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/3scale/apicast-operator/pkg/k8sutils"
)
// MutateFn is a function which mutates the existing object into it's desired state.
type MutateFn func(existing, desired k8sutils.KubernetesObject) (bool, error)
func CreateOnlyMutator(existing, desired k8sutils.KubernetesObject) (bool, error) {
return false, nil
}
type BaseReconciler struct {
// client should be a split client that reads objects from
// the cache and writes to the Kubernetes APIServer
client client.Client
// apiClientReader should be a client that directly reads objects
// from the Kubernetes APIServer
apiClientReader client.Reader
scheme *runtime.Scheme
logger logr.Logger
}
func NewBaseReconciler(client client.Client, apiClientReader client.Reader, scheme *runtime.Scheme, logger logr.Logger) BaseReconciler {
return BaseReconciler{
client: client,
apiClientReader: apiClientReader,
scheme: scheme,
logger: logger,
}
}
func (b *BaseReconciler) Client() client.Client {
return b.client
}
func (b *BaseReconciler) APIClientReader() client.Reader {
return b.apiClientReader
}
func (b *BaseReconciler) Scheme() *runtime.Scheme {
return b.scheme
}
func (b *BaseReconciler) Logger() logr.Logger {
return b.logger
}
// ReconcileResource attempts to mutate the existing state
// in order to match the desired state. The object's desired state must be reconciled
// with the existing state inside the passed in callback MutateFn.
//
// obj: Object of the same type as the 'desired' object.
//
// Used to read the resource from the kubernetes cluster.
// Could be zero-valued initialized object.
//
// desired: Object representing the desired state
//
// It returns an error.
func (b *BaseReconciler) ReconcileResource(ctx context.Context, obj, desired k8sutils.KubernetesObject, mutateFn MutateFn) error {
key := client.ObjectKeyFromObject(desired)
if err := b.Client().Get(ctx, key, obj); err != nil {
if !errors.IsNotFound(err) {
return err
}
// Not found
if !k8sutils.IsObjectTaggedToDelete(desired) {
return b.createResource(ctx, desired)
}
// Marked for deletion and not found. Nothing to do.
return nil
}
// item found successfully
if k8sutils.IsObjectTaggedToDelete(desired) {
return b.deleteResource(ctx, desired)
}
update, err := mutateFn(obj, desired)
if err != nil {
return err
}
if update {
return b.updateResource(ctx, obj)
}
return nil
}
func (b *BaseReconciler) createResource(ctx context.Context, obj k8sutils.KubernetesObject) error {
b.Logger().Info(fmt.Sprintf("Created object %s", k8sutils.ObjectInfo(obj)))
return b.Client().Create(ctx, obj)
}
func (b *BaseReconciler) updateResource(ctx context.Context, obj k8sutils.KubernetesObject) error {
b.Logger().Info(fmt.Sprintf("Updated object %s", k8sutils.ObjectInfo(obj)))
return b.Client().Update(ctx, obj)
}
func (b *BaseReconciler) deleteResource(ctx context.Context, obj k8sutils.KubernetesObject) error {
b.Logger().Info(fmt.Sprintf("Delete object %s", k8sutils.ObjectInfo(obj)))
return b.Client().Delete(ctx, obj)
}