Skip to content

Commit 4168648

Browse files
Merge pull request #2152 from anik120/catsrc-metrics
feat(metrics): Emit metrics for CatalogSource state
2 parents cc47b63 + d83b00c commit 4168648

File tree

5 files changed

+163
-1
lines changed

5 files changed

+163
-1
lines changed

pkg/controller/operators/catalog/operator.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ func (o *Operator) syncSourceState(state grpc.SourceState) {
400400
o.sourcesLastUpdate.Set(o.now().Time)
401401

402402
o.logger.Infof("state.Key.Namespace=%s state.Key.Name=%s state.State=%s", state.Key.Namespace, state.Key.Name, state.State.String())
403+
metrics.RegisterCatalogSourceState(state.Key.Name, state.Key.Namespace, state.State)
403404

404405
switch state.State {
405406
case connectivity.Ready:
@@ -517,6 +518,8 @@ func (o *Operator) handleCatSrcDeletion(obj interface{}) {
517518
o.logger.WithError(err).Warn("error closing client")
518519
}
519520
o.logger.WithField("source", sourceKey).Info("removed client for deleted catalogsource")
521+
522+
metrics.DeleteCatalogSourceStateMetric(catsrc.GetName(), catsrc.GetNamespace())
520523
}
521524

522525
func validateSourceType(logger *logrus.Entry, in *v1alpha1.CatalogSource) (out *v1alpha1.CatalogSource, continueSync bool, _ error) {

pkg/metrics/metrics.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"time"
55

66
"github.com/prometheus/client_golang/prometheus"
7+
"google.golang.org/grpc/connectivity"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
89
"k8s.io/apimachinery/pkg/labels"
910

@@ -141,6 +142,14 @@ var (
141142
},
142143
)
143144

145+
catalogSourceReady = prometheus.NewGaugeVec(
146+
prometheus.GaugeOpts{
147+
Name: "catalogsource_ready",
148+
Help: "State of a CatalogSource. 1 indicates that the CatalogSource is in a READY state. 0 indicates CatalogSource is in a Non READY state.",
149+
},
150+
[]string{NAMESPACE_LABEL, NAME_LABEL},
151+
)
152+
144153
// exported since it's not handled by HandleMetrics
145154
CSVUpgradeCount = prometheus.NewCounter(
146155
prometheus.CounterOpts{
@@ -206,6 +215,7 @@ func RegisterCatalog() {
206215
prometheus.MustRegister(installPlanCount)
207216
prometheus.MustRegister(subscriptionCount)
208217
prometheus.MustRegister(catalogSourceCount)
218+
prometheus.MustRegister(catalogSourceReady)
209219
prometheus.MustRegister(SubscriptionSyncCount)
210220
prometheus.MustRegister(dependencyResolutionSummary)
211221
}
@@ -214,6 +224,19 @@ func CounterForSubscription(name, installedCSV, channelName, packageName, planAp
214224
return SubscriptionSyncCount.WithLabelValues(name, installedCSV, channelName, packageName, planApprovalStrategy)
215225
}
216226

227+
func RegisterCatalogSourceState(name, namespace string, state connectivity.State) {
228+
switch state {
229+
case connectivity.Ready:
230+
catalogSourceReady.WithLabelValues(namespace, name).Set(1)
231+
default:
232+
catalogSourceReady.WithLabelValues(namespace, name).Set(0)
233+
}
234+
}
235+
236+
func DeleteCatalogSourceStateMetric(name, namespace string) {
237+
catalogSourceReady.DeleteLabelValues(namespace, name)
238+
}
239+
217240
func DeleteCSVMetric(oldCSV *olmv1alpha1.ClusterServiceVersion) {
218241
// Delete the old CSV metrics
219242
csvAbnormal.DeleteLabelValues(oldCSV.Namespace, oldCSV.Name, oldCSV.Spec.Version.String(), string(oldCSV.Status.Phase), string(oldCSV.Status.Reason))

test/e2e/like_metric_matcher_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ func WithName(name string) MetricPredicate {
5151
return WithLabel("name", name)
5252
}
5353

54+
func WithNamespace(namespace string) MetricPredicate {
55+
return WithLabel("namespace", namespace)
56+
}
57+
5458
func WithChannel(channel string) MetricPredicate {
5559
return WithLabel("channel", channel)
5660
}

test/e2e/metrics_e2e_test.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,24 @@ package e2e
55
import (
66
"bytes"
77
"context"
8+
"fmt"
89
"regexp"
910
"strings"
11+
"sync"
1012

13+
"github.com/blang/semver/v4"
1114
. "github.com/onsi/ginkgo"
1215
. "github.com/onsi/gomega"
1316
io_prometheus_client "github.com/prometheus/client_model/go"
1417
"github.com/prometheus/common/expfmt"
1518
corev1 "k8s.io/api/core/v1"
19+
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
1620
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1721
"k8s.io/apimachinery/pkg/util/net"
1822

1923
"github.com/operator-framework/api/pkg/operators/v1alpha1"
2024
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
25+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
2126
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
2227
"github.com/operator-framework/operator-lifecycle-manager/test/e2e/ctx"
2328
)
@@ -266,6 +271,110 @@ var _ = Describe("Metrics are generated for OLM managed resources", func() {
266271
})
267272
})
268273
})
274+
275+
Context("Metrics emitted by CatalogSources", func() {
276+
When("A valid CatalogSource object is created", func() {
277+
var (
278+
name = "metrics-catsrc-valid"
279+
cleanup func()
280+
)
281+
BeforeEach(func() {
282+
mainPackageName := genName("nginx-")
283+
284+
mainPackageStable := fmt.Sprintf("%s-stable", mainPackageName)
285+
286+
stableChannel := "stable"
287+
288+
mainCRD := newCRD(genName("ins-"))
289+
mainCSV := newCSV(mainPackageStable, testNamespace, "", semver.MustParse("0.1.0"), []apiextensions.CustomResourceDefinition{mainCRD}, nil, nil)
290+
291+
mainManifests := []registry.PackageManifest{
292+
{
293+
PackageName: mainPackageName,
294+
Channels: []registry.PackageChannel{
295+
{Name: stableChannel, CurrentCSVName: mainPackageStable},
296+
},
297+
DefaultChannelName: stableChannel,
298+
},
299+
}
300+
_, cleanupAll := createInternalCatalogSource(c, crc, name, testNamespace, mainManifests, []apiextensions.CustomResourceDefinition{mainCRD}, []v1alpha1.ClusterServiceVersion{mainCSV})
301+
302+
var once sync.Once
303+
cleanup = func() {
304+
once.Do(cleanupAll)
305+
}
306+
})
307+
AfterEach(func() {
308+
cleanup()
309+
})
310+
It("emits metrics for the catalogSource", func() {
311+
Eventually(func() []Metric {
312+
return getMetricsFromPod(c, getPodWithLabel(c, "app=catalog-operator"), "8081")
313+
}).Should(And(
314+
ContainElement(LikeMetric(
315+
WithFamily("catalog_source_count"),
316+
WithValueGreaterThan(0),
317+
)),
318+
ContainElement(LikeMetric(
319+
WithFamily("catalogsource_ready"),
320+
WithName(name),
321+
WithNamespace(testNamespace),
322+
WithValue(1),
323+
)),
324+
))
325+
})
326+
When("The CatalogSource object is deleted", func() {
327+
BeforeEach(func() {
328+
cleanup()
329+
})
330+
It("deletes the metrics for the CatalogSource", func() {
331+
Eventually(func() []Metric {
332+
return getMetricsFromPod(c, getPodWithLabel(c, "app=catalog-operator"), "8081")
333+
}).Should(And(
334+
Not(ContainElement(LikeMetric(
335+
WithFamily("catalogsource_ready"),
336+
WithName(name),
337+
WithNamespace(testNamespace),
338+
)))))
339+
})
340+
})
341+
})
342+
343+
When("A CatalogSource object is in an invalid state", func() {
344+
var (
345+
name = "metrics-catsrc-invalid"
346+
cleanup func()
347+
)
348+
BeforeEach(func() {
349+
_, cleanup = createInvalidGRPCCatalogSource(crc, name, testNamespace)
350+
})
351+
AfterEach(func() {
352+
cleanup()
353+
})
354+
It("emits metrics for the CatlogSource with a Value greater than 0", func() {
355+
Eventually(func() []Metric {
356+
return getMetricsFromPod(c, getPodWithLabel(c, "app=catalog-operator"), "8081")
357+
}).Should(And(
358+
ContainElement(LikeMetric(
359+
WithFamily("catalogsource_ready"),
360+
WithName(name),
361+
WithNamespace(testNamespace),
362+
WithValue(0),
363+
)),
364+
))
365+
Consistently(func() []Metric {
366+
return getMetricsFromPod(c, getPodWithLabel(c, "app=catalog-operator"), "8081")
367+
}, "3m").Should(And(
368+
ContainElement(LikeMetric(
369+
WithFamily("catalogsource_ready"),
370+
WithName(name),
371+
WithNamespace(testNamespace),
372+
WithValue(0),
373+
)),
374+
))
375+
})
376+
})
377+
})
269378
})
270379

271380
func getPodWithLabel(client operatorclient.ClientInterface, label string) *corev1.Pod {

test/e2e/util_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,30 @@ func buildServiceAccountCleanupFunc(t GinkgoTInterface, c operatorclient.ClientI
521521
}
522522
}
523523

524+
func createInvalidGRPCCatalogSource(crc versioned.Interface, name, namespace string) (*v1alpha1.CatalogSource, cleanupFunc) {
525+
526+
catalogSource := &v1alpha1.CatalogSource{
527+
TypeMeta: metav1.TypeMeta{
528+
Kind: v1alpha1.CatalogSourceKind,
529+
APIVersion: v1alpha1.CatalogSourceCRDAPIVersion,
530+
},
531+
ObjectMeta: metav1.ObjectMeta{
532+
Name: name,
533+
Namespace: namespace,
534+
},
535+
Spec: v1alpha1.CatalogSourceSpec{
536+
SourceType: "grpc",
537+
Image: "localhost:0/not/exists:catsrc",
538+
},
539+
}
540+
541+
ctx.Ctx().Logf("Creating catalog source %s in namespace %s...", name, namespace)
542+
catalogSource, err := crc.OperatorsV1alpha1().CatalogSources(namespace).Create(context.TODO(), catalogSource, metav1.CreateOptions{})
543+
Expect(err).ToNot(HaveOccurred())
544+
ctx.Ctx().Logf("Catalog source %s created", name)
545+
return catalogSource, buildCatalogSourceCleanupFunc(crc, namespace, catalogSource)
546+
}
547+
524548
func createInternalCatalogSource(c operatorclient.ClientInterface, crc versioned.Interface, name, namespace string, manifests []registry.PackageManifest, crds []apiextensions.CustomResourceDefinition, csvs []v1alpha1.ClusterServiceVersion) (*v1alpha1.CatalogSource, cleanupFunc) {
525549
configMap, configMapCleanup := createConfigMapForCatalogData(c, name, namespace, manifests, crds, csvs)
526550

@@ -539,7 +563,6 @@ func createInternalCatalogSource(c operatorclient.ClientInterface, crc versioned
539563
ConfigMap: configMap.GetName(),
540564
},
541565
}
542-
catalogSource.SetNamespace(namespace)
543566

544567
ctx.Ctx().Logf("Creating catalog source %s in namespace %s...", name, namespace)
545568
catalogSource, err := crc.OperatorsV1alpha1().CatalogSources(namespace).Create(context.TODO(), catalogSource, metav1.CreateOptions{})

0 commit comments

Comments
 (0)