From 3042e85788ae0c3437b82ea7197c1c7ee35e83ad Mon Sep 17 00:00:00 2001 From: Aline Abler Date: Mon, 21 Aug 2023 16:19:12 +0200 Subject: [PATCH] Remove unneeded source key properties --- pkg/invoice/invoice_golden_test.go | 4 +- pkg/report/report.go | 4 +- pkg/sourcekey/sourcekey.go | 34 ++++++----- pkg/sourcekey/sourcekey_test.go | 94 +++++++++--------------------- 4 files changed, 52 insertions(+), 84 deletions(-) diff --git a/pkg/invoice/invoice_golden_test.go b/pkg/invoice/invoice_golden_test.go index eb73f6f..255046b 100644 --- a/pkg/invoice/invoice_golden_test.go +++ b/pkg/invoice/invoice_golden_test.go @@ -64,8 +64,8 @@ func (q fakeQuerier) Query(ctx context.Context, query string, ts time.Time, _ .. res = append(res, &model.Sample{ Metric: map[model.LabelName]model.LabelValue{ "product": model.LabelValue(k), - "category": model.LabelValue(fmt.Sprintf("%s:%s", sk.Zone, sk.Namespace)), - "tenant": model.LabelValue(sk.Tenant), + "category": model.LabelValue(fmt.Sprintf("%s:%s", sk.Part(1), sk.Part(3))), + "tenant": model.LabelValue(sk.Part(2)), }, Value: s.Value, }) diff --git a/pkg/report/report.go b/pkg/report/report.go index a706e44..5f62312 100644 --- a/pkg/report/report.go +++ b/pkg/report/report.go @@ -118,10 +118,10 @@ func processSample(ctx context.Context, tx *sqlx.Tx, ts time.Time, query db.Quer var upsertedTenant db.Tenant err = upsertTenant(ctx, tx, &upsertedTenant, db.Tenant{ - Source: skey.Tenant, + Source: skey.Tenant(), }, ts) if err != nil { - return fmt.Errorf("failed to upsert tenant '%s': %w", skey.Tenant, err) + return fmt.Errorf("failed to upsert tenant '%s': %w", skey.Tenant(), err) } var upsertedCategory db.Category diff --git a/pkg/sourcekey/sourcekey.go b/pkg/sourcekey/sourcekey.go index 63ad3d8..f599a1a 100644 --- a/pkg/sourcekey/sourcekey.go +++ b/pkg/sourcekey/sourcekey.go @@ -13,14 +13,7 @@ const elementSeparator = ":" // SourceKey represents a source key to look up dimensions objects (currently queries and products). // It implements the lookup logic found in https://kb.vshn.ch/appuio-cloud/references/architecture/metering-data-flow.html#_system_idea. type SourceKey struct { - Query string - Zone string - Tenant string - Namespace string - - Class string - - Parts []string + parts []string } // Parse parses a source key in the format of "query:zone:tenant:namespace:class" or "query:zone:tenant:namespace". @@ -29,18 +22,31 @@ func Parse(raw string) (SourceKey, error) { if parts[len(parts)-1] == "" { parts = parts[0 : len(parts)-1] } - if len(parts) == 4 { - return SourceKey{parts[0], parts[1], parts[2], parts[3], "", parts}, nil - } else if len(parts) >= 5 { - return SourceKey{parts[0], parts[1], parts[2], parts[3], parts[4], parts}, nil + if len(parts) >= 4 { + return SourceKey{parts}, nil } return SourceKey{}, fmt.Errorf("expected key with at least 4 elements separated by `%s` got %d", elementSeparator, len(parts)) } +// Tenant returns the third element of the source key which was historically used as the tenant. +// +// Deprecated: We would like to get rid of this and read the tenant from a metric label. +func (k SourceKey) Tenant() string { + return k.parts[2] +} + +// Part returns the i-th part of the source key, or an empty string if no such part exists +func (k SourceKey) Part(i int) string { + if i < len(k.parts) { + return k.parts[i] + } + return "" +} + // String returns the string representation "query:zone:tenant:namespace:class" of the key. func (k SourceKey) String() string { - return strings.Join(k.Parts, elementSeparator) + return strings.Join(k.parts, elementSeparator) } // LookupKeys generates lookup keys for a dimension object in the database. @@ -48,7 +54,7 @@ func (k SourceKey) String() string { func (k SourceKey) LookupKeys() []string { keys := make([]string, 0) - currentKeyBase := k.Parts + currentKeyBase := k.parts for len(currentKeyBase) > 1 { // For the base key of a given length l, the inner l-2 elements are to be replaced with wildcards in all possible combinations. diff --git a/pkg/sourcekey/sourcekey_test.go b/pkg/sourcekey/sourcekey_test.go index f0d7749..8b6fa89 100644 --- a/pkg/sourcekey/sourcekey_test.go +++ b/pkg/sourcekey/sourcekey_test.go @@ -1,85 +1,57 @@ -package sourcekey_test +package sourcekey import ( "testing" "github.com/stretchr/testify/require" - - "github.com/appuio/appuio-cloud-reporting/pkg/sourcekey" ) func TestParseInvalidKey(t *testing.T) { - _, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2") + _, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2") require.Error(t, err) } -func TestParseWithClass(t *testing.T) { - k, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:ssd") +func TestParseWithclass(t *testing.T) { + k, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:ssd") require.NoError(t, err) - require.Equal(t, sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Class: "ssd", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"}, + require.Equal(t, SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"}, }, k) } -func TestParseWithoutClass(t *testing.T) { - k, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234") +func TestParseWithoutclass(t *testing.T) { + k, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234") require.NoError(t, err) - require.Equal(t, sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, + require.Equal(t, SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, }, k) } -func TestParseWithEmptyClass(t *testing.T) { - k, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:") +func TestParseWithEmptyclass(t *testing.T) { + k, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:") require.NoError(t, err) - require.Equal(t, sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, + require.Equal(t, SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, }, k) } -func TestStringWithClass(t *testing.T) { - key := sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Class: "ssd", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"}, +func TestStringWithclass(t *testing.T) { + key := SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"}, } require.Equal(t, "appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:ssd", key.String()) } -func TestStringWithoutClass(t *testing.T) { - key := sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, +func TestStringWithoutclass(t *testing.T) { + key := SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, } require.Equal(t, "appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234", key.String()) } -func TestGenerateSourceKeysWithoutClass(t *testing.T) { - keys := sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, +func TestGenerateSourceKeysWithoutclass(t *testing.T) { + keys := SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"}, }.LookupKeys() require.Equal(t, []string{ @@ -94,14 +66,9 @@ func TestGenerateSourceKeysWithoutClass(t *testing.T) { }, keys) } -func TestGenerateSourceKeysWithClass(t *testing.T) { - keys := sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Class: "ssd", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"}, +func TestGenerateSourceKeysWithclass(t *testing.T) { + keys := SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"}, }.LookupKeys() require.Equal(t, []string{ @@ -125,13 +92,8 @@ func TestGenerateSourceKeysWithClass(t *testing.T) { } func TestGenerateSourceKeysWithSixElements(t *testing.T) { - keys := sourcekey.SourceKey{ - Query: "appuio_cloud_storage", - Zone: "c-appuio-cloudscale-lpg-2", - Tenant: "acme-corp", - Namespace: "sparkling-sound-1234", - Class: "ssd", - Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd", "exoscale"}, + keys := SourceKey{ + parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd", "exoscale"}, }.LookupKeys() require.Equal(t, []string{