Skip to content

Commit ef83f8a

Browse files
committed
Implement component override functionality for Config resource
This commit adds the ability to mark components as unmanaged in the bpfman-operator, preventing the operator from creating or updating specific objects. The implementation includes: - Added ComponentOverride struct to Config API with fields for kind, group, namespace, name, and unmanaged flag - Modified assureResource function to check for overrides and skip management of unmanaged components - Implemented isOverridden helper function to match objects against override specifications - Added tests to verify override functionality works correctly across all component types Signed-off-by: Andreas Karis <[email protected]>
1 parent 7ec8677 commit ef83f8a

File tree

3 files changed

+253
-21
lines changed

3 files changed

+253
-21
lines changed

apis/v1alpha1/config_types.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ type ConfigSpec struct {
5757
// Namespace holds the namespace where bpfman-operator resources shall be
5858
// deployed.
5959
Namespace string `json:"namespace,omitempty"`
60+
61+
// overrides is list of overides for components that are managed by
62+
// the operator. Marking a component unmanaged will prevent
63+
// the operator from creating or updating the object.
64+
// +listType=map
65+
// +listMapKey=kind
66+
// +listMapKey=group
67+
// +listMapKey=namespace
68+
// +listMapKey=name
69+
// +optional
70+
Overrides []ComponentOverride `json:"overrides,omitempty"`
6071
}
6172

6273
// AgentSpec defines the desired state of the bpfman agent.
@@ -94,3 +105,28 @@ type ConfigList struct {
94105
metav1.ListMeta `json:"metadata,omitempty"`
95106
Items []Config `json:"items"`
96107
}
108+
109+
// ComponentOverride allows overriding the operator's behavior for a component.
110+
// +k8s:deepcopy-gen=true
111+
type ComponentOverride struct {
112+
// kind indentifies which object to override.
113+
// +required
114+
Kind string `json:"kind"`
115+
// group identifies the API group that the kind is in.
116+
// +required
117+
Group string `json:"group"`
118+
119+
// namespace is the component's namespace. If the resource is cluster
120+
// scoped, the namespace should be empty.
121+
// +required
122+
Namespace string `json:"namespace"`
123+
// name is the component's name.
124+
// +required
125+
Name string `json:"name"`
126+
127+
// unmanaged controls if cluster version operator should stop managing the
128+
// resources in this cluster.
129+
// Default: false
130+
// +required
131+
Unmanaged bool `json:"unmanaged"`
132+
}

controllers/bpfman-operator/config.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,22 @@ func (r *BpfmanConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request
147147
}
148148

149149
func (r *BpfmanConfigReconciler) reconcileCM(ctx context.Context, bpfmanConfig *v1alpha1.Config) error {
150-
cm := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{
151-
Name: internal.BpfmanCmName,
152-
Namespace: bpfmanConfig.Spec.Namespace},
150+
cm := &corev1.ConfigMap{
151+
TypeMeta: metav1.TypeMeta{
152+
Kind: "ConfigMap",
153+
APIVersion: "v1",
154+
},
155+
ObjectMeta: metav1.ObjectMeta{
156+
Name: internal.BpfmanCmName,
157+
Namespace: bpfmanConfig.Spec.Namespace,
158+
},
153159
Data: map[string]string{
154160
internal.BpfmanTOML: bpfmanConfig.Spec.Configuration,
155161
internal.BpfmanAgentLogLevel: bpfmanConfig.Spec.Agent.LogLevel,
156162
internal.BpfmanLogLevel: bpfmanConfig.Spec.LogLevel,
157163
},
158164
}
165+
159166
return assureResource(ctx, r, bpfmanConfig, cm, func(existing, desired *corev1.ConfigMap) bool {
160167
return !equality.Semantic.DeepEqual(existing.Data, desired.Data)
161168
})
@@ -371,6 +378,12 @@ func load[T client.Object](t T, path, name string) (T, error) {
371378
// Creates the resource if it doesn't exist, otherwise updates it to match the desired state.
372379
func assureResource[T client.Object](ctx context.Context, r *BpfmanConfigReconciler,
373380
bpfmanConfig *v1alpha1.Config, resource T, needsUpdate func(existing T, desired T) bool) error {
381+
if isOverridden(resource, bpfmanConfig.Spec.Overrides) {
382+
r.Logger.Info("Ignoring object (override in place)",
383+
"type", resource.GetObjectKind(), "namespace", resource.GetNamespace(), "name", resource.GetName())
384+
return nil
385+
}
386+
374387
if err := ctrl.SetControllerReference(bpfmanConfig, resource, r.Scheme); err != nil {
375388
return err
376389
}
@@ -409,6 +422,20 @@ func assureResource[T client.Object](ctx context.Context, r *BpfmanConfigReconci
409422
return nil
410423
}
411424

425+
// isOverridden determines if a given object shall be unmanaged.
426+
func isOverridden(resource client.Object, overrides []v1alpha1.ComponentOverride) bool {
427+
for _, override := range overrides {
428+
if override.Unmanaged &&
429+
override.Kind == resource.GetObjectKind().GroupVersionKind().Kind &&
430+
override.Group == resource.GetObjectKind().GroupVersionKind().Group &&
431+
override.Namespace == resource.GetNamespace() &&
432+
override.Name == resource.GetName() {
433+
return true
434+
}
435+
}
436+
return false
437+
}
438+
412439
// handleDeletion manages the safe deletion of Config resources by
413440
// removing the finalizer to allow Kubernetes garbage collection to
414441
// proceed via owner references.

0 commit comments

Comments
 (0)