@@ -62,6 +62,7 @@ import (
6262
6363 networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
6464 infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1"
65+ ovnv1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1"
6566 telemetryv1 "github.com/openstack-k8s-operators/telemetry-operator/api/v1beta1"
6667 availability "github.com/openstack-k8s-operators/telemetry-operator/pkg/availability"
6768 ceilometer "github.com/openstack-k8s-operators/telemetry-operator/pkg/ceilometer"
@@ -127,6 +128,7 @@ func (r *MetricStorageReconciler) GetLogger(ctx context.Context) logr.Logger {
127128//+kubebuilder:rbac:groups=monitoring.rhobs,resources=alertmanagers,verbs=get;list;watch;update;patch;delete
128129//+kubebuilder:rbac:groups=network.openstack.org,resources=ipsets,verbs=get;list;watch
129130//+kubebuilder:rbac:groups=rabbitmq.com,resources=rabbitmqclusters,verbs=get;list;watch
131+ //+kubebuilder:rbac:groups=ovn.openstack.org,resources=ovnnorthds,verbs=get;list;watch
130132//+kubebuilder:rbac:groups=observability.openshift.io,resources=uiplugins,verbs=get;list;watch;create;patch
131133//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete
132134//+kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch
@@ -860,6 +862,11 @@ func (r *MetricStorageReconciler) createScrapeConfigs(
860862 if err != nil {
861863 return ctrl.Result {}, err
862864 }
865+ // ScrapeConfig for OVN Northd metrics
866+ err = r .createOVNNorthdScrapeConfig (ctx , instance , helper , serviceLabels )
867+ if err != nil {
868+ return ctrl.Result {}, err
869+ }
863870
864871 instance .Status .Conditions .MarkTrue (telemetryv1 .ScrapeConfigReadyCondition , condition .ReadyMessage )
865872 return ctrl.Result {}, nil
@@ -934,6 +941,72 @@ func (r *MetricStorageReconciler) createComputeScrapeConfig(
934941 return nil
935942}
936943
944+ func (r * MetricStorageReconciler ) createOVNNorthdScrapeConfig (
945+ ctx context.Context ,
946+ instance * telemetryv1.MetricStorage ,
947+ helper * helper.Helper ,
948+ serviceLabels map [string ]string ,
949+ ) error {
950+ Log := r .GetLogger (ctx )
951+
952+ // Discover OVN Northd metrics services using label selectors
953+ // This matches the labels set in controllers/ovnnorthd_controller.go:647-649
954+ serviceList := & corev1.ServiceList {}
955+ listOpts := []client.ListOption {
956+ client .InNamespace (instance .Namespace ),
957+ client.MatchingLabels {
958+ "type" : "metrics" ,
959+ "service" : "ovn-northd" ,
960+ },
961+ }
962+ err := helper .GetClient ().List (ctx , serviceList , listOpts ... )
963+ if err != nil {
964+ Log .Info (fmt .Sprintf ("Cannot get OVN Northd metrics services. Scrape configs not created. Error: %s" , err ))
965+ return nil
966+ }
967+
968+ if len (serviceList .Items ) == 0 {
969+ Log .Info ("No OVN Northd metrics services found" )
970+ return nil
971+ }
972+
973+ // Create targets from discovered services
974+ var ovnNorthdTargets []string
975+ for _ , svc := range serviceList .Items {
976+ // Find the metrics port (should be named "metrics" with port 1981)
977+ for _ , port := range svc .Spec .Ports {
978+ if port .Name == "metrics" {
979+ serviceRoute := fmt .Sprintf ("%s.%s.svc" , svc .Name , svc .Namespace )
980+ target := net .JoinHostPort (serviceRoute , strconv .Itoa (int (port .Port )))
981+ ovnNorthdTargets = append (ovnNorthdTargets , target )
982+ Log .Info (fmt .Sprintf ("Found OVN Northd metrics service: %s" , target ))
983+ break
984+ }
985+ }
986+ }
987+
988+ if len (ovnNorthdTargets ) == 0 {
989+ Log .Info ("No valid OVN Northd metrics targets found" )
990+ return nil
991+ }
992+
993+ // Create scrape config for OVN Northd metrics
994+ ovnNorthdCfgName := fmt .Sprintf ("%s-ovn-northd" , telemetry .ServiceName )
995+ desiredScrapeConfig := metricstorage .ScrapeConfig (
996+ instance ,
997+ serviceLabels ,
998+ ovnNorthdTargets ,
999+ instance .Spec .PrometheusTLS .Enabled (),
1000+ )
1001+ err = r .createServiceScrapeConfig (ctx , instance , Log , "OVN Northd" ,
1002+ ovnNorthdCfgName , desiredScrapeConfig )
1003+ if err != nil {
1004+ return err
1005+ }
1006+
1007+ return nil
1008+ }
1009+
9371010func (r * MetricStorageReconciler ) createDashboardObjects (ctx context.Context , instance * telemetryv1.MetricStorage , helper * helper.Helper , eventHandler handler.EventHandler ) (ctrl.Result , error ) {
9381011 Log := r .GetLogger (ctx )
9391012 uiPluginObj := & obsui.UIPlugin {
@@ -1347,6 +1420,35 @@ func (r *MetricStorageReconciler) SetupWithManager(ctx context.Context, mgr ctrl
13471420 return nil
13481421 }
13491422
1423+ ovnMetricsServiceWatchFn := func (_ context.Context , o client.Object ) []reconcile.Request {
1424+ result := []reconcile.Request {}
1425+
1426+ // Only watch OVN northd metrics services
1427+ if labels := o .GetLabels (); labels != nil {
1428+ if labels ["type" ] == "metrics" && labels ["service" ] == "ovn-northd" {
1429+ // get all metricstorage CRs in the same namespace
1430+ metricStorages := & telemetryv1.MetricStorageList {}
1431+ listOpts := []client.ListOption {
1432+ client .InNamespace (o .GetNamespace ()),
1433+ }
1434+ if err := r .Client .List (context .Background (), metricStorages , listOpts ... ); err != nil {
1435+ Log .Error (err , "Unable to retrieve MetricStorage CRs %w" )
1436+ return nil
1437+ }
1438+
1439+ for _ , cr := range metricStorages .Items {
1440+ name := client.ObjectKey {
1441+ Namespace : o .GetNamespace (),
1442+ Name : cr .Name ,
1443+ }
1444+ Log .Info (fmt .Sprintf ("OVN metrics service %s changed, reconciling MetricStorage CR %s" , o .GetName (), cr .Name ))
1445+ result = append (result , reconcile.Request {NamespacedName : name })
1446+ }
1447+ }
1448+ }
1449+ return result
1450+ }
1451+
13501452 reconcileAllMetricStoragesWatchFn := func (_ context.Context , o client.Object ) []reconcile.Request {
13511453 result := []reconcile.Request {}
13521454
@@ -1412,6 +1514,8 @@ func (r *MetricStorageReconciler) SetupWithManager(ctx context.Context, mgr ctrl
14121514 For (& telemetryv1.MetricStorage {}).
14131515 Watches (& corev1.Service {},
14141516 handler .EnqueueRequestsFromMapFunc (prometheusServiceWatchFn )).
1517+ Watches (& corev1.Service {},
1518+ handler .EnqueueRequestsFromMapFunc (ovnMetricsServiceWatchFn )).
14151519 Watches (
14161520 & corev1.Secret {},
14171521 handler .EnqueueRequestsFromMapFunc (r .findObjectsForSrc ),
@@ -1426,6 +1530,11 @@ func (r *MetricStorageReconciler) SetupWithManager(ctx context.Context, mgr ctrl
14261530 & rabbitmqv1.RabbitmqCluster {},
14271531 handler .EnqueueRequestsFromMapFunc (reconcileAllMetricStoragesWatchFn ),
14281532 ).
1533+ Watches (
1534+ & ovnv1.OVNNorthd {},
1535+ handler .EnqueueRequestsFromMapFunc (reconcileAllMetricStoragesWatchFn ),
1536+ builder .WithPredicates (predicate.ResourceVersionChangedPredicate {}),
1537+ ).
14291538 Watches (
14301539 & telemetryv1.Ceilometer {},
14311540 handler .EnqueueRequestsFromMapFunc (reconcileAllMetricStoragesWatchFn ),
0 commit comments