Skip to content

Commit 79c7825

Browse files
Merge pull request #239 from timflannagan/bz-1952576
Bug 1952576: Emit CSV metric on startup
2 parents 78d2b0a + 7baca83 commit 79c7825

File tree

5 files changed

+132
-0
lines changed

5 files changed

+132
-0
lines changed

staging/operator-lifecycle-manager/cmd/olm/main.go

Lines changed: 5 additions & 0 deletions
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()),

staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go

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

680+
func (a *Operator) EnsureCSVMetric() error {
681+
csvs, err := a.lister.OperatorsV1alpha1().ClusterServiceVersionLister().List(labels.Everything())
682+
if err != nil {
683+
return err
684+
}
685+
for _, csv := range csvs {
686+
logger := a.logger.WithFields(logrus.Fields{
687+
"name": csv.GetName(),
688+
"namespace": csv.GetNamespace(),
689+
"self": csv.GetSelfLink(),
690+
})
691+
logger.Debug("emitting metrics for existing CSV")
692+
metrics.EmitCSVMetric(csv, csv)
693+
}
694+
return nil
695+
}
696+
680697
func (a *Operator) syncGCObject(obj interface{}) (syncError error) {
681698
metaObj, ok := obj.(metav1.Object)
682699
if !ok {

staging/operator-lifecycle-manager/test/e2e/metrics_e2e_test.go

Lines changed: 88 additions & 0 deletions
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,48 @@ 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+
Eventually(func() []Metric {
153+
return getMetricsFromPod(c, getPodWithLabel(c, "app=olm-operator"))
154+
}).Should(ContainElement(LikeMetric(
155+
WithFamily("csv_succeeded"),
156+
WithName(csv.Name),
157+
WithValue(1),
158+
)))
159+
})
160+
})
161+
})
119162
})
120163

121164
Context("Metrics emitted by objects during operator installation", func() {
@@ -396,6 +439,51 @@ func getPodWithLabel(client operatorclient.ClientInterface, label string) *corev
396439
return &podList.Items[0]
397440
}
398441

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

vendor/github.com/operator-framework/operator-lifecycle-manager/cmd/olm/main.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/operator.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)