Skip to content

Commit 131ecfa

Browse files
Josef Karasekanik120
Josef Karasek
authored andcommitted
Emit CSV metric on startup (operator-framework#2216)
Signed-off-by: Josef Karasek <[email protected]>
1 parent 1471b65 commit 131ecfa

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

cmd/olm/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ func main() {
211211
op.Run(ctx)
212212
<-op.Ready()
213213

214+
// Emit CSV metric
215+
if err = op.EnsureCSVMetric(); err != nil {
216+
logger.WithError(err).Fatalf("error emitting metrics for existing CSV")
217+
}
218+
214219
if *writeStatusName != "" {
215220
operatorstatus.MonitorClusterStatus(*writeStatusName, op.AtLevel(), ctx.Done(), opClient, configClient, crClient)
216221
}

pkg/controller/operators/olm/operator.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,23 @@ func (a *Operator) RegisterCSVWatchNotification(csvNotification csvutility.Watch
600600
a.csvNotification = csvNotification
601601
}
602602

603+
func (a *Operator) EnsureCSVMetric() error {
604+
csvs, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().List(labels.Everything())
605+
if err != nil {
606+
return err
607+
}
608+
for _, csv := range csvs {
609+
logger := a.logger.WithFields(logrus.Fields{
610+
"name": csv.GetName(),
611+
"namespace": csv.GetNamespace(),
612+
"self": csv.GetSelfLink(),
613+
})
614+
logger.Debug("emitting metrics for existing CSV")
615+
metrics.EmitCSVMetric(csv, csv)
616+
}
617+
return nil
618+
}
619+
603620
func (a *Operator) syncGCObject(obj interface{}) (syncError error) {
604621
metaObj, ok := obj.(metav1.Object)
605622
if !ok {

test/e2e/metrics_e2e_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
. "github.com/onsi/gomega"
1515
io_prometheus_client "github.com/prometheus/client_model/go"
1616
"github.com/prometheus/common/expfmt"
17+
appsv1 "k8s.io/api/apps/v1"
1718
corev1 "k8s.io/api/core/v1"
1819
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1920
"k8s.io/apimachinery/pkg/util/net"
@@ -108,6 +109,44 @@ var _ = Describe("Metrics are generated for OLM managed resources", func() {
108109
})
109110
})
110111
})
112+
113+
When("a CSV is created", func() {
114+
var (
115+
cleanupCSV cleanupFunc
116+
csv v1alpha1.ClusterServiceVersion
117+
)
118+
BeforeEach(func() {
119+
packageName := genName("csv-test-")
120+
packageStable := fmt.Sprintf("%s-stable", packageName)
121+
csv = newCSV(packageStable, testNamespace, "", semver.MustParse("0.1.0"), nil, nil, nil)
122+
123+
var err error
124+
_, err = createCSV(c, crc, csv, testNamespace, false, false)
125+
Expect(err).ToNot(HaveOccurred())
126+
_, err = fetchCSV(crc, csv.Name, testNamespace, csvSucceededChecker)
127+
Expect(err).ToNot(HaveOccurred())
128+
})
129+
AfterEach(func() {
130+
if cleanupCSV != nil {
131+
cleanupCSV()
132+
}
133+
})
134+
It("emits a CSV metrics", func() {
135+
Expect(getMetricsFromPod(c, getPodWithLabel(c, "app=olm-operator"))).To(
136+
ContainElement(LikeMetric(WithFamily("csv_succeeded"), WithName(csv.Name), WithValue(1))),
137+
)
138+
})
139+
When("the OLM pod restarts", func() {
140+
BeforeEach(func() {
141+
restartDeploymentWithLabel(c, "app=olm-operator")
142+
})
143+
It("CSV metric is preserved", func() {
144+
Expect(getMetricsFromPod(c, getPodWithLabel(c, "app=olm-operator"))).To(
145+
ContainElement(LikeMetric(WithFamily("csv_succeeded"), WithName(csv.Name), WithValue(1))),
146+
)
147+
})
148+
})
149+
})
111150
})
112151

113152
Context("Metrics emitted by objects during operator installation", func() {
@@ -284,6 +323,51 @@ func getPodWithLabel(client operatorclient.ClientInterface, label string) *corev
284323
return &podList.Items[0]
285324
}
286325

326+
func getDeploymentWithLabel(client operatorclient.ClientInterface, label string) *appsv1.Deployment {
327+
listOptions := metav1.ListOptions{LabelSelector: label}
328+
var deploymentList *appsv1.DeploymentList
329+
EventuallyWithOffset(1, func() (numDeps int, err error) {
330+
deploymentList, err = client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).List(context.TODO(), listOptions)
331+
if deploymentList != nil {
332+
numDeps = len(deploymentList.Items)
333+
}
334+
335+
return
336+
}).Should(Equal(1), "expected exactly one Deployment")
337+
338+
return &deploymentList.Items[0]
339+
}
340+
341+
func restartDeploymentWithLabel(client operatorclient.ClientInterface, l string) {
342+
d := getDeploymentWithLabel(client, l)
343+
z := int32(0)
344+
oldZ := *d.Spec.Replicas
345+
d.Spec.Replicas = &z
346+
_, err := client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Update(context.TODO(), d, metav1.UpdateOptions{})
347+
Expect(err).ToNot(HaveOccurred())
348+
349+
EventuallyWithOffset(1, func() (replicas int32, err error) {
350+
deployment, err := client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Get(context.TODO(), d.Name, metav1.GetOptions{})
351+
if deployment != nil {
352+
replicas = deployment.Status.Replicas
353+
}
354+
return
355+
}).Should(Equal(int32(0)), "expected exactly 0 Deployments")
356+
357+
updated := getDeploymentWithLabel(client, l)
358+
updated.Spec.Replicas = &oldZ
359+
_, err = client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Update(context.TODO(), updated, metav1.UpdateOptions{})
360+
Expect(err).ToNot(HaveOccurred())
361+
362+
EventuallyWithOffset(1, func() (replicas int32, err error) {
363+
deployment, err := client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Get(context.TODO(), d.Name, metav1.GetOptions{})
364+
if deployment != nil {
365+
replicas = deployment.Status.Replicas
366+
}
367+
return
368+
}).Should(Equal(oldZ), "expected exactly 1 Deployment")
369+
}
370+
287371
func extractMetricPortFromPod(pod *corev1.Pod) string {
288372
for _, container := range pod.Spec.Containers {
289373
for _, port := range container.Ports {

0 commit comments

Comments
 (0)