From 6b50e2d730b0e3e9042d05e01ffea232a3c1b4a1 Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Tue, 9 Dec 2025 17:14:22 -0600 Subject: [PATCH] Unified Storage: Update yaml decoding for quotas to accomodate top-level overrides key (#115049) * update yaml decoding for quotas to accomodate top-level overrides key * update test * fix test indentation --- pkg/storage/unified/resource/quotas.go | 19 +-- pkg/storage/unified/resource/quotas_test.go | 136 +++++++++++--------- pkg/storage/unified/resource/server_test.go | 9 +- 3 files changed, 90 insertions(+), 74 deletions(-) diff --git a/pkg/storage/unified/resource/quotas.go b/pkg/storage/unified/resource/quotas.go index d956a6da017..03fe515559e 100644 --- a/pkg/storage/unified/resource/quotas.go +++ b/pkg/storage/unified/resource/quotas.go @@ -47,13 +47,14 @@ type Overrides struct { /* This service loads overrides (currently just quotas) from a YAML file with the following yaml structure: -"123": +overrides: + "123": quotas: - grafana.dashboard.app/dashboards: - limit: 1500 - grafana.folder.app/folders: - limit: 1500 + dashboard.grafana.app/dashboards: + limit: 1500 + folder.grafana.app/folders: + limit: 1500 */ func NewOverridesService(_ context.Context, logger log.Logger, reg prometheus.Registerer, tracer trace.Tracer, opts ReloadOptions) (*OverridesService, error) { // shouldn't be empty since we use file path existence to determine if we should enable the service @@ -76,12 +77,14 @@ func NewOverridesService(_ context.Context, logger log.Logger, reg prometheus.Re ReloadPeriod: opts.ReloadPeriod, LoadPath: []string{opts.FilePath}, Loader: func(r io.Reader) (interface{}, error) { - var tenants map[string]NamespaceOverrides + var raw struct { + Overrides map[string]NamespaceOverrides `yaml:"overrides"` + } decoder := yaml.NewDecoder(r) - if err := decoder.Decode(&tenants); err != nil { + if err := decoder.Decode(&raw); err != nil { return nil, err } - return &Overrides{Namespaces: tenants}, nil + return &Overrides{Namespaces: raw.Overrides}, nil }, } diff --git a/pkg/storage/unified/resource/quotas_test.go b/pkg/storage/unified/resource/quotas_test.go index 97f9f355af6..097a02d7444 100644 --- a/pkg/storage/unified/resource/quotas_test.go +++ b/pkg/storage/unified/resource/quotas_test.go @@ -27,10 +27,11 @@ func TestNewQuotaService(t *testing.T) { opts: ReloadOptions{}, setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -105,10 +106,11 @@ func TestQuotaService_ConfigReload(t *testing.T) { // Create a temporary config file tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - initialConfig := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 + initialConfig := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(initialConfig), 0644)) @@ -139,14 +141,15 @@ func TestQuotaService_ConfigReload(t *testing.T) { assert.Equal(t, 1500, quota.Limit, "initial quota should be 1500") // Update the config file with new values - updatedConfig := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 2500 -"456": - quotas: - grafana.folder.app/folders: - limit: 3000 + updatedConfig := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 2500 + "456": + quotas: + grafana.folder.app/folders: + limit: 3000 ` require.NoError(t, os.WriteFile(tmpFile, []byte(updatedConfig), 0644)) @@ -183,10 +186,11 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns custom quota for matching tenant and resource", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -204,10 +208,11 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns default quota when tenant not found", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -225,10 +230,11 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns default quota when resource not found", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -246,10 +252,11 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "handles namespace without stacks- prefix", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -284,12 +291,13 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "handles multiple resources for same tenant", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 - grafana.folder.app/folders: - limit: 2500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 + grafana.folder.app/folders: + limit: 2500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -307,12 +315,13 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns error when namespace is empty", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 - grafana.folder.app/folders: - limit: 2500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 + grafana.folder.app/folders: + limit: 2500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -330,12 +339,13 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns error when group is empty", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 - grafana.folder.app/folders: - limit: 2500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 + grafana.folder.app/folders: + limit: 2500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -353,12 +363,13 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns error when resource is empty", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 - grafana.folder.app/folders: - limit: 2500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 + grafana.folder.app/folders: + limit: 2500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile @@ -376,12 +387,13 @@ func TestQuotaService_GetQuota(t *testing.T) { name: "returns error when all fields are empty", setupFile: func(t *testing.T) string { tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - grafana.dashboard.app/dashboards: - limit: 1500 - grafana.folder.app/folders: - limit: 2500 + content := `overrides: + "123": + quotas: + grafana.dashboard.app/dashboards: + limit: 1500 + grafana.folder.app/folders: + limit: 2500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644)) return tmpFile diff --git a/pkg/storage/unified/resource/server_test.go b/pkg/storage/unified/resource/server_test.go index b4ab0cdff2a..0b0bbcfba13 100644 --- a/pkg/storage/unified/resource/server_test.go +++ b/pkg/storage/unified/resource/server_test.go @@ -643,10 +643,11 @@ func TestGetQuotaUsage(t *testing.T) { t.Run("returns usage and limit successfully", func(t *testing.T) { // Create a temporary overrides config file tmpFile := filepath.Join(t.TempDir(), "overrides.yaml") - content := `"123": - quotas: - dashboard.grafana.app/dashboards: - limit: 500 + content := `overrides: + "123": + quotas: + dashboard.grafana.app/dashboards: + limit: 500 ` require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644))