Skip to content

Commit 11efdd6

Browse files
stubbiclaude
andcommitted
feat(controller): reconcile optional HTTPRoute
Add a reconcileHTTPRoute step using controllerutil.CreateOrUpdate over an unstructured object, deleting the route when disabled and reporting via the HTTPRouteReady condition. Add a +kubebuilder:rbac marker for gateway.networking.k8s.io httproutes and keep the generated ClusterRole and Helm chart RBAC in sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent a78f60d commit 11efdd6

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

charts/hermes-operator/templates/clusterrole.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ rules:
2020
- apiGroups: [batch]
2121
resources: [cronjobs, jobs]
2222
verbs: [create, delete, get, list, patch, update, watch]
23+
- apiGroups: [gateway.networking.k8s.io]
24+
resources: [httproutes]
25+
verbs: [create, delete, get, list, patch, update, watch]
2326
- apiGroups: [hermes.agent]
2427
resources: [hermesclusterdefaults]
2528
verbs: [get, list, patch, update, watch]

config/rbac/role.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ rules:
6767
- patch
6868
- update
6969
- watch
70+
- apiGroups:
71+
- gateway.networking.k8s.io
72+
resources:
73+
- httproutes
74+
verbs:
75+
- create
76+
- delete
77+
- get
78+
- list
79+
- patch
80+
- update
81+
- watch
7082
- apiGroups:
7183
- hermes.agent
7284
resources:

internal/controller/hermesinstance_controller.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const (
7676
// +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete
7777
// +kubebuilder:rbac:groups="",resources=services;configmaps;persistentvolumeclaims;secrets;serviceaccounts;events,verbs=get;list;watch;create;update;patch;delete
7878
// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies;ingresses,verbs=get;list;watch;create;update;patch;delete
79+
// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch;create;update;patch;delete
7980
// +kubebuilder:rbac:groups=policy,resources=poddisruptionbudgets,verbs=get;list;watch;create;update;patch;delete
8081
// +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=get;list;watch;create;update;patch;delete
8182
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
@@ -131,6 +132,7 @@ func (r *HermesInstanceReconciler) Reconcile(ctx context.Context, req ctrl.Reque
131132
{"PDB", hermesv1.ConditionTypePDBReady, r.reconcilePDB},
132133
{"HPA", hermesv1.ConditionTypeHPAReady, r.reconcileHPA},
133134
{"Ingress", hermesv1.ConditionTypeIngressReady, r.reconcileIngress},
135+
{"HTTPRoute", hermesv1.ConditionTypeHTTPRouteReady, r.reconcileHTTPRoute},
134136
{"ServiceMonitor", hermesv1.ConditionTypeServiceMonitorReady, r.reconcileServiceMonitor},
135137
{"PrometheusRule", hermesv1.ConditionTypePrometheusRuleReady, r.reconcilePrometheusRule},
136138
{"GrafanaDashboard", hermesv1.ConditionTypeGrafanaDashboardReady, r.reconcileGrafanaDashboards},
@@ -392,6 +394,34 @@ func (r *HermesInstanceReconciler) reconcileIngress(ctx context.Context, inst *h
392394
return err
393395
}
394396

397+
func (r *HermesInstanceReconciler) reconcileHTTPRoute(ctx context.Context, inst *hermesv1.HermesInstance) error {
398+
spec := inst.Spec.Networking.HTTPRoute
399+
enabled := spec != nil && resources.BoolValue(spec.Enabled)
400+
if !enabled {
401+
obj := &unstructured.Unstructured{}
402+
obj.SetGroupVersionKind(resources.HTTPRouteGVK())
403+
obj.SetName(resources.HTTPRouteName(inst))
404+
obj.SetNamespace(inst.Namespace)
405+
return r.deleteIfExists(ctx, obj)
406+
}
407+
desired := resources.BuildHTTPRoute(inst)
408+
if err := controllerutil.SetControllerReference(inst, desired, r.Scheme); err != nil {
409+
return err
410+
}
411+
obj := &unstructured.Unstructured{}
412+
obj.SetGroupVersionKind(resources.HTTPRouteGVK())
413+
obj.SetName(desired.GetName())
414+
obj.SetNamespace(desired.GetNamespace())
415+
_, err := controllerutil.CreateOrUpdate(ctx, r.Client, obj, func() error {
416+
obj.Object["spec"] = desired.Object["spec"]
417+
obj.SetLabels(resources.MergePreservingForeign(obj.GetLabels(), desired.GetLabels(), operatorLabelPrefix))
418+
obj.SetAnnotations(resources.MergePreservingForeign(obj.GetAnnotations(), desired.GetAnnotations(), operatorLabelPrefix))
419+
obj.SetOwnerReferences(desired.GetOwnerReferences())
420+
return nil
421+
})
422+
return err
423+
}
424+
395425
func (r *HermesInstanceReconciler) reconcileServiceMonitor(ctx context.Context, inst *hermesv1.HermesInstance) error {
396426
// If the Prometheus Operator CRDs are not present there is nothing to manage:
397427
// no ServiceMonitor can exist, so skip entirely (don't even try to delete).

0 commit comments

Comments
 (0)