Skip to content

Commit de4bebe

Browse files
author
Josef Karasek
authored
Emit CSV metric on startup (#2216)
Signed-off-by: Josef Karasek <[email protected]>
1 parent 3eb0d7b commit de4bebe

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

cmd/olm/main.go

+5
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ func main() {
171171
op.Run(ctx)
172172
<-op.Ready()
173173

174+
// Emit CSV metric
175+
if err = op.EnsureCSVMetric(); err != nil {
176+
logger.WithError(err).Fatalf("error emitting metrics for existing CSV")
177+
}
178+
174179
if *writeStatusName != "" {
175180
reconciler, err := openshift.NewClusterOperatorReconciler(
176181
openshift.WithClient(mgr.GetClient()),

pkg/controller/operators/olm/operator.go

+17
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,23 @@ func (a *Operator) RegisterCSVWatchNotification(csvNotification csvutility.Watch
655655
a.csvNotification = csvNotification
656656
}
657657

658+
func (a *Operator) EnsureCSVMetric() error {
659+
csvs, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().List(labels.Everything())
660+
if err != nil {
661+
return err
662+
}
663+
for _, csv := range csvs {
664+
logger := a.logger.WithFields(logrus.Fields{
665+
"name": csv.GetName(),
666+
"namespace": csv.GetNamespace(),
667+
"self": csv.GetSelfLink(),
668+
})
669+
logger.Debug("emitting metrics for existing CSV")
670+
metrics.EmitCSVMetric(csv, csv)
671+
}
672+
return nil
673+
}
674+
658675
func (a *Operator) syncGCObject(obj interface{}) (syncError error) {
659676
metaObj, ok := obj.(metav1.Object)
660677
if !ok {

test/e2e/metrics_e2e_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
. "github.com/onsi/gomega"
1717
io_prometheus_client "github.com/prometheus/client_model/go"
1818
"github.com/prometheus/common/expfmt"
19+
appsv1 "k8s.io/api/apps/v1"
1920
corev1 "k8s.io/api/core/v1"
2021
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
2122
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -116,6 +117,44 @@ var _ = Describe("Metrics are generated for OLM managed resources", func() {
116117
})
117118
})
118119
})
120+
121+
When("a CSV is created", func() {
122+
var (
123+
cleanupCSV cleanupFunc
124+
csv v1alpha1.ClusterServiceVersion
125+
)
126+
BeforeEach(func() {
127+
packageName := genName("csv-test-")
128+
packageStable := fmt.Sprintf("%s-stable", packageName)
129+
csv = newCSV(packageStable, testNamespace, "", semver.MustParse("0.1.0"), nil, nil, nil)
130+
131+
var err error
132+
_, err = createCSV(c, crc, csv, testNamespace, false, false)
133+
Expect(err).ToNot(HaveOccurred())
134+
_, err = fetchCSV(crc, csv.Name, testNamespace, csvSucceededChecker)
135+
Expect(err).ToNot(HaveOccurred())
136+
})
137+
AfterEach(func() {
138+
if cleanupCSV != nil {
139+
cleanupCSV()
140+
}
141+
})
142+
It("emits a CSV metrics", func() {
143+
Expect(getMetricsFromPod(c, getPodWithLabel(c, "app=olm-operator"))).To(
144+
ContainElement(LikeMetric(WithFamily("csv_succeeded"), WithName(csv.Name), WithValue(1))),
145+
)
146+
})
147+
When("the OLM pod restarts", func() {
148+
BeforeEach(func() {
149+
restartDeploymentWithLabel(c, "app=olm-operator")
150+
})
151+
It("CSV metric is preserved", func() {
152+
Expect(getMetricsFromPod(c, getPodWithLabel(c, "app=olm-operator"))).To(
153+
ContainElement(LikeMetric(WithFamily("csv_succeeded"), WithName(csv.Name), WithValue(1))),
154+
)
155+
})
156+
})
157+
})
119158
})
120159

121160
Context("Metrics emitted by objects during operator installation", func() {
@@ -396,6 +435,51 @@ func getPodWithLabel(client operatorclient.ClientInterface, label string) *corev
396435
return &podList.Items[0]
397436
}
398437

438+
func getDeploymentWithLabel(client operatorclient.ClientInterface, label string) *appsv1.Deployment {
439+
listOptions := metav1.ListOptions{LabelSelector: label}
440+
var deploymentList *appsv1.DeploymentList
441+
EventuallyWithOffset(1, func() (numDeps int, err error) {
442+
deploymentList, err = client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).List(context.TODO(), listOptions)
443+
if deploymentList != nil {
444+
numDeps = len(deploymentList.Items)
445+
}
446+
447+
return
448+
}).Should(Equal(1), "expected exactly one Deployment")
449+
450+
return &deploymentList.Items[0]
451+
}
452+
453+
func restartDeploymentWithLabel(client operatorclient.ClientInterface, l string) {
454+
d := getDeploymentWithLabel(client, l)
455+
z := int32(0)
456+
oldZ := *d.Spec.Replicas
457+
d.Spec.Replicas = &z
458+
_, err := client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Update(context.TODO(), d, metav1.UpdateOptions{})
459+
Expect(err).ToNot(HaveOccurred())
460+
461+
EventuallyWithOffset(1, func() (replicas int32, err error) {
462+
deployment, err := client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Get(context.TODO(), d.Name, metav1.GetOptions{})
463+
if deployment != nil {
464+
replicas = deployment.Status.Replicas
465+
}
466+
return
467+
}).Should(Equal(int32(0)), "expected exactly 0 Deployments")
468+
469+
updated := getDeploymentWithLabel(client, l)
470+
updated.Spec.Replicas = &oldZ
471+
_, err = client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Update(context.TODO(), updated, metav1.UpdateOptions{})
472+
Expect(err).ToNot(HaveOccurred())
473+
474+
EventuallyWithOffset(1, func() (replicas int32, err error) {
475+
deployment, err := client.KubernetesInterface().AppsV1().Deployments(operatorNamespace).Get(context.TODO(), d.Name, metav1.GetOptions{})
476+
if deployment != nil {
477+
replicas = deployment.Status.Replicas
478+
}
479+
return
480+
}).Should(Equal(oldZ), "expected exactly 1 Deployment")
481+
}
482+
399483
func extractMetricPortFromPod(pod *corev1.Pod) string {
400484
for _, container := range pod.Spec.Containers {
401485
for _, port := range container.Ports {

0 commit comments

Comments
 (0)