Skip to content

Commit 30fb446

Browse files
Enable ingestion of the exposed metrics by openshift-montoring (#410)
* enable ingestion of the exposed metrics by openshift-montoring * add velero sm and svc * incorporate new OADP API * Hardcoded stuff to make this work * fix labels * add unit tests * add monitoring uts * update permissions in csv * fix unit tests and remove comments * updaye csv * update alm-examples * fix perms * remove prometheus role and rolebinding creation * update e2e tests velero label Co-authored-by: dymurray <[email protected]>
1 parent 8d8575a commit 30fb446

File tree

13 files changed

+736
-23
lines changed

13 files changed

+736
-23
lines changed

bundle/manifests/oadp-operator.clusterserviceversion.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ spec:
358358
- pods
359359
- services
360360
- serviceaccounts
361+
- endpoints
361362
verbs:
362363
- list
363364
- get
@@ -391,6 +392,18 @@ spec:
391392
- patch
392393
- update
393394
- watch
395+
- apiGroups:
396+
- monitoring.coreos.com
397+
resources:
398+
- servicemonitors
399+
verbs:
400+
- get
401+
- create
402+
- list
403+
- delete
404+
- update
405+
- patch
406+
- watch
394407
- apiGroups:
395408
- authentication.k8s.io
396409
resources:

config/manager/manager.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ kind: Namespace
33
metadata:
44
labels:
55
control-plane: controller-manager
6+
openshift.io/cluster-monitoring: "true"
67
name: system
78
---
89
apiVersion: apps/v1

config/rbac/role.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ rules:
110110
- pods
111111
- services
112112
- serviceaccounts
113+
- endpoints
113114
verbs:
114115
- list
115116
- get
@@ -143,3 +144,15 @@ rules:
143144
- patch
144145
- update
145146
- watch
147+
- apiGroups:
148+
- monitoring.coreos.com
149+
resources:
150+
- servicemonitors
151+
verbs:
152+
- get
153+
- create
154+
- list
155+
- delete
156+
- update
157+
- patch
158+
- watch

controllers/dpa_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ func (r *DPAReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
9595
r.ReconcileVolumeSnapshotLocations,
9696
r.ReconcileVeleroDeployment,
9797
r.ReconcileResticDaemonset,
98+
r.ReconcileVeleroServiceMonitor,
99+
r.ReconcileVeleroMetricsSVC,
98100
)
99101

100102
if err != nil {

controllers/monitor.go

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package controllers
2+
3+
import (
4+
"fmt"
5+
"github.com/go-logr/logr"
6+
oadpv1alpha1 "github.com/openshift/oadp-operator/api/v1alpha1"
7+
"github.com/openshift/oadp-operator/pkg/common"
8+
monitor "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
9+
corev1 "k8s.io/api/core/v1"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
"k8s.io/apimachinery/pkg/util/intstr"
12+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
13+
)
14+
15+
func (r *DPAReconciler) ReconcileVeleroServiceMonitor(log logr.Logger) (bool, error) {
16+
17+
dpa := oadpv1alpha1.DataProtectionApplication{}
18+
if err := r.Get(r.Context, r.NamespacedName, &dpa); err != nil {
19+
return false, err
20+
}
21+
22+
serviceMonitor := &monitor.ServiceMonitor{
23+
ObjectMeta: metav1.ObjectMeta{
24+
Name: "openshift-adp-velero-metrics-sm",
25+
Namespace: r.NamespacedName.Namespace,
26+
},
27+
}
28+
29+
op, err := controllerutil.CreateOrUpdate(r.Context, r.Client, serviceMonitor, func() error {
30+
31+
if serviceMonitor.ObjectMeta.CreationTimestamp.IsZero() {
32+
serviceMonitor.Spec.Selector = metav1.LabelSelector{
33+
MatchLabels: map[string]string{
34+
"app.kubernetes.io/name": common.Velero,
35+
"app.kubernetes.io/instance": dpa.Name,
36+
"app.kubernetes.io/managed-by": common.OADPOperator,
37+
"app.kubernetes.io/component": Server,
38+
oadpv1alpha1.OadpOperatorLabel: "True",
39+
},
40+
}
41+
}
42+
43+
// update service monitor
44+
return r.buildVeleroServiceMonitor(serviceMonitor, &dpa)
45+
})
46+
47+
if err != nil {
48+
return false, err
49+
}
50+
51+
//TODO: Review service monitor status and report errors and conditions
52+
53+
if op == controllerutil.OperationResultCreated || op == controllerutil.OperationResultUpdated {
54+
// Trigger event to indicate service monitor was created or updated
55+
r.EventRecorder.Event(serviceMonitor,
56+
corev1.EventTypeNormal,
57+
"VeleroServiceMonitorReconciled",
58+
fmt.Sprintf("performed %s on dpa service monitor %s/%s", op, serviceMonitor.Namespace, serviceMonitor.Name),
59+
)
60+
}
61+
return true, nil
62+
}
63+
64+
func (r *DPAReconciler) buildVeleroServiceMonitor(serviceMonitor *monitor.ServiceMonitor, dpa *oadpv1alpha1.DataProtectionApplication) error {
65+
66+
if dpa == nil {
67+
return fmt.Errorf("dpa CR cannot be nil")
68+
}
69+
70+
if serviceMonitor == nil {
71+
return fmt.Errorf("service monitor cannot be nil")
72+
}
73+
74+
// Setting controller owner reference on the service monitor
75+
err := controllerutil.SetControllerReference(dpa, serviceMonitor, r.Scheme)
76+
if err != nil {
77+
return err
78+
}
79+
80+
serviceMonitor.Spec.Selector = metav1.LabelSelector{
81+
MatchLabels: map[string]string{
82+
"app.kubernetes.io/name": common.Velero,
83+
"app.kubernetes.io/instance": dpa.Name,
84+
"app.kubernetes.io/managed-by": common.OADPOperator,
85+
"app.kubernetes.io/component": Server,
86+
oadpv1alpha1.OadpOperatorLabel: "True",
87+
},
88+
}
89+
90+
serviceMonitor.Labels = map[string]string{
91+
"app.kubernetes.io/name": common.Velero,
92+
"app.kubernetes.io/instance": dpa.Name,
93+
"app.kubernetes.io/managed-by": common.OADPOperator,
94+
"app.kubernetes.io/component": Server,
95+
oadpv1alpha1.OadpOperatorLabel: "True",
96+
}
97+
98+
serviceMonitor.Spec.Endpoints = []monitor.Endpoint{
99+
{
100+
Interval: "30s",
101+
Port: "monitoring",
102+
},
103+
}
104+
105+
//serviceMonitor.Spec.JobLabel = "app"
106+
107+
serviceMonitor.Spec.NamespaceSelector = monitor.NamespaceSelector{
108+
MatchNames: []string{
109+
dpa.Namespace,
110+
},
111+
}
112+
113+
return nil
114+
}
115+
116+
func (r *DPAReconciler) ReconcileVeleroMetricsSVC(log logr.Logger) (bool, error) {
117+
dpa := oadpv1alpha1.DataProtectionApplication{}
118+
if err := r.Get(r.Context, r.NamespacedName, &dpa); err != nil {
119+
return false, err
120+
}
121+
122+
svc := corev1.Service{
123+
ObjectMeta: metav1.ObjectMeta{
124+
Name: "openshift-adp-velero-metrics-svc",
125+
Namespace: r.NamespacedName.Namespace,
126+
},
127+
}
128+
129+
// Create SVC
130+
op, err := controllerutil.CreateOrUpdate(r.Context, r.Client, &svc, func() error {
131+
// TODO: check for svc status condition errors and respond here
132+
err := r.updateVeleroMetricsSVC(&svc, &dpa)
133+
134+
return err
135+
})
136+
if err != nil {
137+
return false, err
138+
}
139+
if op == controllerutil.OperationResultCreated || op == controllerutil.OperationResultUpdated {
140+
// Trigger event to indicate SVC was created or updated
141+
r.EventRecorder.Event(&svc,
142+
corev1.EventTypeNormal,
143+
"VeleroMetricsServiceReconciled",
144+
fmt.Sprintf("performed %s on dpa metrics service %s/%s", op, svc.Namespace, svc.Name),
145+
)
146+
}
147+
148+
return true, nil
149+
}
150+
151+
func (r *DPAReconciler) updateVeleroMetricsSVC(svc *corev1.Service, dpa *oadpv1alpha1.DataProtectionApplication) error {
152+
// Setting controller owner reference on the metrics svc
153+
err := controllerutil.SetControllerReference(dpa, svc, r.Scheme)
154+
if err != nil {
155+
return err
156+
}
157+
158+
// when updating the spec fields we update each field individually
159+
// to get around the immutable fields
160+
svc.Spec.Selector = map[string]string{
161+
"app.kubernetes.io/name": common.Velero,
162+
"app.kubernetes.io/instance": dpa.Name,
163+
"app.kubernetes.io/managed-by": common.OADPOperator,
164+
"app.kubernetes.io/component": Server,
165+
oadpv1alpha1.OadpOperatorLabel: "True",
166+
}
167+
168+
svc.Spec.Type = corev1.ServiceTypeClusterIP
169+
svc.Spec.Ports = []corev1.ServicePort{
170+
{
171+
Name: "monitoring",
172+
Port: int32(8085),
173+
TargetPort: intstr.IntOrString{
174+
IntVal: int32(8085),
175+
},
176+
},
177+
}
178+
179+
svc.Labels = map[string]string{
180+
"app.kubernetes.io/name": common.Velero,
181+
"app.kubernetes.io/instance": dpa.Name,
182+
"app.kubernetes.io/managed-by": common.OADPOperator,
183+
"app.kubernetes.io/component": Server,
184+
oadpv1alpha1.OadpOperatorLabel: "True",
185+
}
186+
return nil
187+
}

0 commit comments

Comments
 (0)