diff --git a/internal/knowledge/kpis/plugins/sap/flavor_running_vms.go b/internal/knowledge/kpis/plugins/sap/flavor_running_vms.go index 31616b2e..4adfcbc4 100644 --- a/internal/knowledge/kpis/plugins/sap/flavor_running_vms.go +++ b/internal/knowledge/kpis/plugins/sap/flavor_running_vms.go @@ -18,6 +18,7 @@ type FlavorRunningVMs struct { FlavorName string `db:"flavor_name"` AvailabilityZone string `db:"availability_zone"` RunningVMs float64 `db:"running_vms"` + ProjectID string `db:"project_id"` } type FlavorRunningVMsKPI struct { @@ -40,6 +41,7 @@ func (k *FlavorRunningVMsKPI) Init(db *db.DB, client client.Client, opts conf.Ra []string{ "flavor_name", "availability_zone", + "project_id", }, nil, ) @@ -55,6 +57,7 @@ func (k *FlavorRunningVMsKPI) Collect(ch chan<- prometheus.Metric) { query := ` SELECT + tenant_id AS project_id, flavor_name, COALESCE(os_ext_az_availability_zone, 'unknown') AS availability_zone, COUNT(*) AS running_vms @@ -62,17 +65,17 @@ func (k *FlavorRunningVMsKPI) Collect(ch chan<- prometheus.Metric) { WHERE status != 'DELETED' GROUP BY + project_id, flavor_name, os_ext_az_availability_zone ORDER BY - flavor_name; + project_id; ` if _, err := k.DB.Select(&results, query); err != nil { slog.Error("failed to select running vms per flavor", "err", err) return } - slog.Info("flavor running vms results", "results", results) for _, r := range results { ch <- prometheus.MustNewConstMetric( k.flavorRunningVMs, @@ -80,6 +83,7 @@ func (k *FlavorRunningVMsKPI) Collect(ch chan<- prometheus.Metric) { r.RunningVMs, r.FlavorName, r.AvailabilityZone, + r.ProjectID, ) } } diff --git a/internal/knowledge/kpis/plugins/sap/flavor_running_vms_test.go b/internal/knowledge/kpis/plugins/sap/flavor_running_vms_test.go index 99052180..03ce84a1 100644 --- a/internal/knowledge/kpis/plugins/sap/flavor_running_vms_test.go +++ b/internal/knowledge/kpis/plugins/sap/flavor_running_vms_test.go @@ -40,21 +40,31 @@ func TestFlavorRunningVMsKPI_Collect(t *testing.T) { ID: "id-1", FlavorName: "small", OSEXTAvailabilityZone: "zone1", + TenantID: "project-1", }, &nova.Server{ ID: "id-2", FlavorName: "medium", OSEXTAvailabilityZone: "zone1", + TenantID: "project-1", }, &nova.Server{ ID: "id-3", FlavorName: "medium", OSEXTAvailabilityZone: "zone2", + TenantID: "project-1", }, &nova.Server{ ID: "id-4", FlavorName: "medium", OSEXTAvailabilityZone: "zone2", + TenantID: "project-1", + }, + &nova.Server{ + ID: "id-5", + FlavorName: "medium", + OSEXTAvailabilityZone: "zone2", + TenantID: "project-2", }, } @@ -75,6 +85,7 @@ func TestFlavorRunningVMsKPI_Collect(t *testing.T) { FlavorName string AvailabilityZone string RunningVMs float64 + ProjectID string } metrics := make(map[string]FlavorRunningVMsMetric, 0) @@ -92,38 +103,48 @@ func TestFlavorRunningVMsKPI_Collect(t *testing.T) { flavor := labels["flavor_name"] availabilityZone := labels["availability_zone"] + projectID := labels["project_id"] - key := flavor + "|" + availabilityZone + key := flavor + "|" + availabilityZone + "|" + projectID metrics[key] = FlavorRunningVMsMetric{ FlavorName: flavor, AvailabilityZone: availabilityZone, + ProjectID: projectID, RunningVMs: m.GetGauge().GetValue(), } } expectedMetrics := map[string]FlavorRunningVMsMetric{ - "small|zone1": { + "small|zone1|project-1": { FlavorName: "small", AvailabilityZone: "zone1", + ProjectID: "project-1", RunningVMs: 1, }, - "medium|zone1": { + "medium|zone1|project-1": { FlavorName: "medium", AvailabilityZone: "zone1", RunningVMs: 1, + ProjectID: "project-1", }, - "medium|zone2": { + "medium|zone2|project-1": { FlavorName: "medium", AvailabilityZone: "zone2", RunningVMs: 2, + ProjectID: "project-1", + }, + "medium|zone2|project-2": { + FlavorName: "medium", + AvailabilityZone: "zone2", + RunningVMs: 1, + ProjectID: "project-2", }, } for key, expected := range expectedMetrics { actual, ok := metrics[key] if !ok { - t.Logf("%v", metrics) t.Errorf("expected metric %q not found", key) continue }