Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions internal/knowledge/kpis/plugins/sap/flavor_running_vms.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
)
Expand All @@ -55,31 +57,33 @@ 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
FROM ` + nova.Server{}.TableName() + `
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,
prometheus.GaugeValue,
r.RunningVMs,
r.FlavorName,
r.AvailabilityZone,
r.ProjectID,
)
}
}
31 changes: 26 additions & 5 deletions internal/knowledge/kpis/plugins/sap/flavor_running_vms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
}

Expand All @@ -75,6 +85,7 @@ func TestFlavorRunningVMsKPI_Collect(t *testing.T) {
FlavorName string
AvailabilityZone string
RunningVMs float64
ProjectID string
}

metrics := make(map[string]FlavorRunningVMsMetric, 0)
Expand All @@ -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
}
Expand Down