diff --git a/internal/collector/capacity_scrape.go b/internal/collector/capacity_scrape.go index 1a1766cfc..e6004586c 100644 --- a/internal/collector/capacity_scrape.go +++ b/internal/collector/capacity_scrape.go @@ -347,11 +347,37 @@ func (c *Collector) processCapacityScrapeTask(_ context.Context, task capacitySc } //for all cluster resources thus updated, recompute project quotas if necessary + needsACDQ := make(map[string]bool) for _, res := range dbOwnedResources { - err := datamodel.ApplyComputedProjectQuota(serviceTypeForID[res.ServiceID], res.Name, c.DB, c.Cluster) + serviceType := serviceTypeForID[res.ServiceID] + err := datamodel.ApplyComputedProjectQuota(serviceType, res.Name, c.DB, c.Cluster) + if err != nil { + return err + } + needsACDQ[serviceType] = true + } + + // for all domain services that had project quotas touched, recompute domain quotas if necessary + if len(needsACDQ) > 0 { + var domainIDs []db.DomainID + err := sqlext.ForeachRow(c.DB, `SELECT id FROM domains`, nil, func(rows *sql.Rows) error { + var domainID db.DomainID + err := rows.Scan(&domainID) + domainIDs = append(domainIDs, domainID) + return err + }) if err != nil { return err } + + for serviceType := range needsACDQ { + for _, domainID := range domainIDs { + err := datamodel.ApplyComputedDomainQuota(c.DB, c.Cluster, domainID, serviceType) + if err != nil { + return err + } + } + } } return nil diff --git a/internal/collector/capacity_scrape_test.go b/internal/collector/capacity_scrape_test.go index 987019a5d..e4d7e728f 100644 --- a/internal/collector/capacity_scrape_test.go +++ b/internal/collector/capacity_scrape_test.go @@ -442,6 +442,8 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { mustT(t, jobloop.ProcessMany(job, s.Ctx, len(s.Cluster.CapacityPlugins))) tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 261 WHERE id = 1 AND service_id = 1 AND name = 'capacity'; + UPDATE domain_resources SET quota = 20 WHERE id = 4 AND service_id = 2 AND name = 'capacity'; UPDATE project_az_resources SET quota = 0 WHERE id = 17 AND resource_id = 2 AND az = 'any'; UPDATE project_az_resources SET quota = 1 WHERE id = 18 AND resource_id = 2 AND az = 'az-one'; UPDATE project_az_resources SET quota = 250 WHERE id = 19 AND resource_id = 2 AND az = 'az-two'; @@ -468,6 +470,7 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { scrapedAt1 := s.Clock.Now().Add(-5 * time.Second) tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 270 WHERE id = 1 AND service_id = 1 AND name = 'capacity'; UPDATE project_az_resources SET quota = 10 WHERE id = 18 AND resource_id = 2 AND az = 'az-one'; UPDATE project_commitments SET confirmed_at = %d, state = 'active' WHERE id = 1; UPDATE project_resources SET quota = 260, backend_quota = 260, desired_backend_quota = 260 WHERE id = 2 AND service_id = 1 AND name = 'capacity'; @@ -482,6 +485,7 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { scrapedAt1 = s.Clock.Now().Add(-5 * time.Second) tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 370 WHERE id = 1 AND service_id = 1 AND name = 'capacity'; UPDATE project_az_resources SET quota = 110 WHERE id = 18 AND resource_id = 2 AND az = 'az-one'; UPDATE project_commitments SET confirmed_at = %d, state = 'active' WHERE id = 2; UPDATE project_commitments SET state = 'pending' WHERE id = 3; @@ -499,6 +503,7 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { scrapedAt2 := s.Clock.Now() tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 31 WHERE id = 4 AND service_id = 2 AND name = 'capacity'; UPDATE project_az_resources SET quota = 0 WHERE id = 26 AND resource_id = 11 AND az = 'any'; UPDATE project_az_resources SET quota = 20 WHERE id = 27 AND resource_id = 11 AND az = 'az-one'; UPDATE project_commitments SET confirmed_at = %d, state = 'active' WHERE id = 4; @@ -516,6 +521,7 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { scrapedAt1 = s.Clock.Now().Add(-5 * time.Second) tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 420 WHERE id = 1 AND service_id = 1 AND name = 'capacity'; UPDATE project_az_resources SET quota = 300 WHERE id = 19 AND resource_id = 2 AND az = 'az-two'; UPDATE project_commitments SET state = 'pending' WHERE id = 7; UPDATE project_commitments SET confirmed_at = %d, state = 'active' WHERE id = 8; @@ -532,6 +538,7 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { scrapedAt2 = s.Clock.Now() tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 44 WHERE id = 4 AND service_id = 2 AND name = 'capacity'; UPDATE project_az_resources SET quota = 0 WHERE id = 20 AND resource_id = 5 AND az = 'any'; UPDATE project_az_resources SET quota = 22 WHERE id = 22 AND resource_id = 5 AND az = 'az-two'; UPDATE project_commitments SET state = 'pending' WHERE id = 10; @@ -545,6 +552,7 @@ func Test_ScanCapacityWithCommitments(t *testing.T) { scrapedAt2 = s.Clock.Now() tr.DBChanges().AssertEqualf(`%s + UPDATE domain_resources SET quota = 32 WHERE id = 4 AND service_id = 2 AND name = 'capacity'; UPDATE project_az_resources SET quota = 8 WHERE id = 20 AND resource_id = 5 AND az = 'any'; UPDATE project_az_resources SET quota = 1 WHERE id = 22 AND resource_id = 5 AND az = 'az-two'; UPDATE project_az_resources SET quota = 2 WHERE id = 28 AND resource_id = 11 AND az = 'az-two'; diff --git a/internal/collector/fixtures/capacity_scrape_with_commitments.sql b/internal/collector/fixtures/capacity_scrape_with_commitments.sql index d314a4c9c..41ec748fd 100644 --- a/internal/collector/fixtures/capacity_scrape_with_commitments.sql +++ b/internal/collector/fixtures/capacity_scrape_with_commitments.sql @@ -28,6 +28,17 @@ INSERT INTO cluster_az_resources (id, resource_id, az, raw_capacity, usage) VALU -- one domain INSERT INTO domains (id, name, uuid) VALUES (1, 'germany', 'uuid-for-germany'); +-- domain_services and domain_resources are fully populated (as ensured by the collector's consistency check) +INSERT INTO domain_services (id, domain_id, type) VALUES (1, 1, 'first'); +INSERT INTO domain_services (id, domain_id, type) VALUES (2, 1, 'second'); + +INSERT INTO domain_resources (id, service_id, name, quota) VALUES (1, 1, 'capacity', 0); +INSERT INTO domain_resources (id, service_id, name, quota) VALUES (2, 1, 'capacity_portion', 0); +INSERT INTO domain_resources (id, service_id, name, quota) VALUES (3, 1, 'things', 0); +INSERT INTO domain_resources (id, service_id, name, quota) VALUES (4, 2, 'capacity', 0); +INSERT INTO domain_resources (id, service_id, name, quota) VALUES (5, 2, 'capacity_portion', 0); +INSERT INTO domain_resources (id, service_id, name, quota) VALUES (6, 2, 'things', 0); + -- two projects INSERT INTO projects (id, domain_id, name, uuid, parent_uuid, has_bursting) VALUES (1, 1, 'berlin', 'uuid-for-berlin', 'uuid-for-germany', FALSE); INSERT INTO projects (id, domain_id, name, uuid, parent_uuid, has_bursting) VALUES (2, 1, 'dresden', 'uuid-for-dresden', 'uuid-for-berlin', FALSE);