-
Notifications
You must be signed in to change notification settings - Fork 4
/
lifecycle.go
131 lines (112 loc) · 3.59 KB
/
lifecycle.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
// Package lifecycle implements the lifecycle hooks
package lifecycle
import (
"context"
"errors"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/logging"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/common"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/decoder"
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/object"
"github.com/cloudnative-pg/cnpg-i/pkg/lifecycle"
corev1 "k8s.io/api/core/v1"
"github.com/cloudnative-pg/cnpg-i-hello-world/internal/config"
"github.com/cloudnative-pg/cnpg-i-hello-world/internal/utils"
"github.com/cloudnative-pg/cnpg-i-hello-world/pkg/metadata"
)
// Implementation is the implementation of the lifecycle handler
type Implementation struct {
lifecycle.UnimplementedOperatorLifecycleServer
}
// GetCapabilities exposes the lifecycle capabilities
func (impl Implementation) GetCapabilities(
_ context.Context,
_ *lifecycle.OperatorLifecycleCapabilitiesRequest,
) (*lifecycle.OperatorLifecycleCapabilitiesResponse, error) {
return &lifecycle.OperatorLifecycleCapabilitiesResponse{
LifecycleCapabilities: []*lifecycle.OperatorLifecycleCapabilities{
{
Group: "",
Kind: "Pod",
OperationTypes: []*lifecycle.OperatorOperationType{
{
Type: lifecycle.OperatorOperationType_TYPE_CREATE,
},
{
Type: lifecycle.OperatorOperationType_TYPE_PATCH,
},
},
},
},
}, nil
}
// LifecycleHook is called when creating Kubernetes services
func (impl Implementation) LifecycleHook(
ctx context.Context,
request *lifecycle.OperatorLifecycleRequest,
) (*lifecycle.OperatorLifecycleResponse, error) {
kind, err := utils.GetKind(request.GetObjectDefinition())
if err != nil {
return nil, err
}
operation := request.GetOperationType().GetType().Enum()
if operation == nil {
return nil, errors.New("no operation set")
}
//nolint: gocritic
switch kind {
case "Pod":
switch *operation {
case lifecycle.OperatorOperationType_TYPE_CREATE, lifecycle.OperatorOperationType_TYPE_PATCH,
lifecycle.OperatorOperationType_TYPE_UPDATE:
return impl.reconcileMetadata(ctx, request)
}
// add any other custom logic to execute based on the operation
}
return &lifecycle.OperatorLifecycleResponse{}, nil
}
// LifecycleHook is called when creating Kubernetes services
func (impl Implementation) reconcileMetadata(
ctx context.Context,
request *lifecycle.OperatorLifecycleRequest,
) (*lifecycle.OperatorLifecycleResponse, error) {
cluster, err := decoder.DecodeClusterJSON(request.GetClusterDefinition())
if err != nil {
return nil, err
}
logger := logging.FromContext(ctx).WithName("cnpg_i_example_lifecyle")
helper := common.NewPlugin(
*cluster,
metadata.PluginName,
)
configuration, valErrs := config.FromParameters(helper)
if len(valErrs) > 0 {
return nil, valErrs[0]
}
pod, err := decoder.DecodePodJSON(request.GetObjectDefinition())
if err != nil {
return nil, err
}
mutatedPod := pod.DeepCopy()
err = object.InjectPluginSidecar(mutatedPod, &corev1.Container{
Name: "pauser",
Image: "registry.k8s.io/pause:3.5",
}, false)
if err != nil {
return nil, err
}
// Apply any custom logic needed here, in this example we just add some metadata to the pod
for key, value := range configuration.Labels {
mutatedPod.Labels[key] = value
}
for key, value := range configuration.Annotations {
mutatedPod.Annotations[key] = value
}
patch, err := object.CreatePatch(mutatedPod, pod)
if err != nil {
return nil, err
}
logger.V(0).Info("generated patch", "content", string(patch), "configuration", configuration)
return &lifecycle.OperatorLifecycleResponse{
JsonPatch: patch,
}, nil
}