Skip to content

Commit 3bb761c

Browse files
authored
Feat: Add servicemonitor for built-in detectors (#588)
* Add servicemonitor for built-in detectors * Address review comments
1 parent 311094f commit 3bb761c

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

controllers/gorch/guardrailsorchestrator_controller.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"github.com/go-logr/logr"
2222
kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1"
23+
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
2324
"github.com/trustyai-explainability/trustyai-service-operator/controllers/metrics"
2425
rbacv1 "k8s.io/api/rbac/v1"
2526
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -410,6 +411,34 @@ func (r *GuardrailsOrchestratorReconciler) Reconcile(ctx context.Context, req ct
410411
}
411412
}
412413

414+
existingSM := &monitoringv1.ServiceMonitor{}
415+
err = r.Get(ctx, types.NamespacedName{Name: orchestrator.Name + "-service-monitor", Namespace: orchestrator.Namespace}, existingSM)
416+
if orchestrator.Spec.EnableBuiltInDetectors {
417+
if err != nil && errors.IsNotFound(err) {
418+
// Define a new route
419+
serviceMonitor := r.createServiceMonitor(ctx, orchestrator)
420+
log.Info("Creating a new Service Monitor", "ServiceMonitor.Namespace", serviceMonitor.Namespace, "ServiceMonitor.Name", serviceMonitor.Name)
421+
err = r.Create(ctx, serviceMonitor)
422+
if err != nil {
423+
r.handleReconciliationErrorWithTrace(ctx, log, orchestrator, err, ReconcileFailed, "Failed to create new ServiceMonitor", "ServiceMonitor.Namespace", serviceMonitor.Namespace, "ServiceMonitor.Name", serviceMonitor.Name)
424+
}
425+
} else if err != nil {
426+
r.handleReconciliationError(ctx, log, orchestrator, err, ReconcileFailed, "Failed to get ServiceMonitor")
427+
return ctrl.Result{}, err
428+
}
429+
} else {
430+
if err == nil {
431+
log.Info("Deleting ServiceMonitor because EnableBuiltInDetectors is false", "ServiceMonitor.Namespace", existingSM.Namespace, "ServiceMonitor.Name", existingSM.Name)
432+
if delErr := r.Delete(ctx, existingSM); delErr != nil && !errors.IsNotFound(delErr) {
433+
r.handleReconciliationErrorWithTrace(ctx, log, orchestrator, delErr, ReconcileFailed, "Failed to delete ServiceMonitor", "ServiceMonitor.Namespace", existingSM.Namespace, "ServiceMonitor.Name", existingSM.Name)
434+
return ctrl.Result{}, delErr
435+
}
436+
} else if err != nil && !errors.IsNotFound(err) {
437+
r.handleReconciliationError(ctx, log, orchestrator, err, ReconcileFailed, "Failed to get ServiceMonitor for deletion")
438+
return ctrl.Result{}, err
439+
}
440+
}
441+
413442
// Finalize reconcilation
414443
_, updateErr := r.reconcileStatuses(ctx, orchestrator)
415444
if updateErr != nil {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package gorch
2+
3+
import (
4+
"context"
5+
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
6+
gorchv1alpha1 "github.com/trustyai-explainability/trustyai-service-operator/api/gorch/v1alpha1"
7+
templateParser "github.com/trustyai-explainability/trustyai-service-operator/controllers/gorch/templates"
8+
"reflect"
9+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
10+
"sigs.k8s.io/controller-runtime/pkg/log"
11+
)
12+
13+
const serviceMonitorTemplatePath = "service-monitor.tmpl.yaml"
14+
15+
type ServiceMonitorConfig struct {
16+
Orchestrator gorchv1alpha1.GuardrailsOrchestrator
17+
}
18+
19+
func (r *GuardrailsOrchestratorReconciler) createServiceMonitor(ctx context.Context, orchestrator *gorchv1alpha1.GuardrailsOrchestrator) *monitoringv1.ServiceMonitor {
20+
21+
serviceMonitorConfig := ServiceMonitorConfig{
22+
Orchestrator: *orchestrator,
23+
}
24+
25+
var serviceMonitor *monitoringv1.ServiceMonitor
26+
serviceMonitor, err := templateParser.ParseResource[monitoringv1.ServiceMonitor](serviceMonitorTemplatePath, serviceMonitorConfig, reflect.TypeOf(&monitoringv1.ServiceMonitor{}))
27+
if err != nil {
28+
log.FromContext(ctx).Error(err, "Failed to parse service monitor template")
29+
}
30+
controllerutil.SetControllerReference(orchestrator, serviceMonitor, r.Scheme)
31+
return serviceMonitor
32+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
apiVersion: monitoring.coreos.com/v1
2+
kind: ServiceMonitor
3+
metadata:
4+
name: {{ .Orchestrator.Name }}-service-monitor
5+
namespace: {{.Orchestrator.Namespace}}
6+
labels:
7+
component: {{ .Orchestrator.Name }}
8+
spec:
9+
endpoints:
10+
- bearerTokenSecret:
11+
key: ''
12+
honorLabels: true
13+
interval: 30s
14+
metricRelabelings:
15+
- action: keep
16+
regex: trustyai_guardrails_.*
17+
sourceLabels:
18+
- __name__
19+
path: /metrics
20+
scheme: http
21+
port: detector-metrics
22+
selector:
23+
matchLabels:
24+
component: {{ .Orchestrator.Name }}
25+
namespaceSelector:
26+
matchNames:
27+
- {{ .Orchestrator.Namespace }}

controllers/gorch/templates/service.tmpl.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ metadata:
77
service.beta.openshift.io/serving-cert-secret-name: {{ .Orchestrator.Name }}-tls
88
labels:
99
app: {{.Orchestrator.Name}}
10-
component: {{.Orchestrator.Name}}
10+
component: {{ .Orchestrator.Name }}
11+
1112
spec:
1213
ipFamilies:
1314
- IPv4
@@ -32,6 +33,12 @@ spec:
3233
protocol: TCP
3334
port: 8034
3435
targetPort: 8034
36+
{{if .Orchestrator.Spec.EnableBuiltInDetectors}}
37+
- name: detector-metrics
38+
protocol: TCP
39+
port: 8080
40+
targetPort: 8080
41+
{{end}}
3542
internalTrafficPolicy: Cluster
3643
type: ClusterIP
3744
ipFamilyPolicy: SingleStack

0 commit comments

Comments
 (0)