From 5d34b28ecba8838ad487c6cee6ba461023471b84 Mon Sep 17 00:00:00 2001 From: Mike Ditton Date: Wed, 20 May 2026 13:33:23 +0200 Subject: [PATCH 1/2] Add allowed namespaces to vshngarage This uses the GarageReferenceGrant to restrict where GarageKeys and GarageBuckets can be provisioned. --- .../functions/vshngarage/deploy.go | 24 ++++++++++++ .../functions/vshngarage/deploy_test.go | 38 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 pkg/comp-functions/functions/vshngarage/deploy_test.go diff --git a/pkg/comp-functions/functions/vshngarage/deploy.go b/pkg/comp-functions/functions/vshngarage/deploy.go index e34803e170..4db03e1bc3 100644 --- a/pkg/comp-functions/functions/vshngarage/deploy.go +++ b/pkg/comp-functions/functions/vshngarage/deploy.go @@ -2,6 +2,7 @@ package vshngarage import ( "context" + "encoding/json" "errors" "fmt" @@ -20,6 +21,25 @@ const ( GarageHost = "GARAGE_URL" ) +// applyAllowedNamespaces decodes the comma-coupled JSON list provided through +// the comp-function xfn-config (key: garageAllowedNamespaces) and injects it +// into the vshngaragecluster chart values. Empty input leaves values +// untouched so older component-appcat releases that don't ship the key keep +// working — the chart simply skips the GarageReferenceGrant template. +func applyAllowedNamespaces(values map[string]any, raw string) error { + if raw == "" { + return nil + } + var allowed []string + if err := json.Unmarshal([]byte(raw), &allowed); err != nil { + return fmt.Errorf("cannot parse garageAllowedNamespaces %q: %w", raw, err) + } + if len(allowed) > 0 { + values["allowedNamespaces"] = allowed + } + return nil +} + func DeployGarage(ctx context.Context, comp *vshnv1.VSHNGarage, svc *runtime.ServiceRuntime) *xfnproto.Result { l := svc.Log @@ -71,6 +91,10 @@ func DeployGarage(ctx context.Context, comp *vshnv1.VSHNGarage, svc *runtime.Ser "storageMetadataSpace": comp.Spec.Parameters.Service.MetadataStorage, } + if err := applyAllowedNamespaces(values, svc.Config.Data["garageAllowedNamespaces"]); err != nil { + return runtime.NewFatalResult(err) + } + connectionDetails := []v1beta1.ConnectionDetail{ { ObjectReference: corev1.ObjectReference{ diff --git a/pkg/comp-functions/functions/vshngarage/deploy_test.go b/pkg/comp-functions/functions/vshngarage/deploy_test.go new file mode 100644 index 0000000000..d45d7566e0 --- /dev/null +++ b/pkg/comp-functions/functions/vshngarage/deploy_test.go @@ -0,0 +1,38 @@ +package vshngarage + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestApplyAllowedNamespaces(t *testing.T) { + t.Run("empty raw leaves values untouched", func(t *testing.T) { + values := map[string]any{"existing": "keep"} + require.NoError(t, applyAllowedNamespaces(values, "")) + _, present := values["allowedNamespaces"] + assert.False(t, present) + assert.Equal(t, "keep", values["existing"]) + }) + + t.Run("populated list lands in values", func(t *testing.T) { + values := map[string]any{} + require.NoError(t, applyAllowedNamespaces(values, `["syn-appcat","team-a"]`)) + assert.Equal(t, []string{"syn-appcat", "team-a"}, values["allowedNamespaces"]) + }) + + t.Run("empty json array leaves values untouched", func(t *testing.T) { + values := map[string]any{} + require.NoError(t, applyAllowedNamespaces(values, `[]`)) + _, present := values["allowedNamespaces"] + assert.False(t, present) + }) + + t.Run("malformed json fails", func(t *testing.T) { + values := map[string]any{} + err := applyAllowedNamespaces(values, `not-json`) + require.Error(t, err) + assert.Contains(t, err.Error(), "cannot parse garageAllowedNamespaces") + }) +} From 249e6d8264f3841b741ddd28ff39876266fb18c3 Mon Sep 17 00:00:00 2001 From: Mike Ditton Date: Tue, 26 May 2026 10:44:19 +0200 Subject: [PATCH 2/2] Move helper function to bottom --- .../functions/vshngarage/deploy.go | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/pkg/comp-functions/functions/vshngarage/deploy.go b/pkg/comp-functions/functions/vshngarage/deploy.go index 4db03e1bc3..5e4da93206 100644 --- a/pkg/comp-functions/functions/vshngarage/deploy.go +++ b/pkg/comp-functions/functions/vshngarage/deploy.go @@ -21,25 +21,6 @@ const ( GarageHost = "GARAGE_URL" ) -// applyAllowedNamespaces decodes the comma-coupled JSON list provided through -// the comp-function xfn-config (key: garageAllowedNamespaces) and injects it -// into the vshngaragecluster chart values. Empty input leaves values -// untouched so older component-appcat releases that don't ship the key keep -// working — the chart simply skips the GarageReferenceGrant template. -func applyAllowedNamespaces(values map[string]any, raw string) error { - if raw == "" { - return nil - } - var allowed []string - if err := json.Unmarshal([]byte(raw), &allowed); err != nil { - return fmt.Errorf("cannot parse garageAllowedNamespaces %q: %w", raw, err) - } - if len(allowed) > 0 { - values["allowedNamespaces"] = allowed - } - return nil -} - func DeployGarage(ctx context.Context, comp *vshnv1.VSHNGarage, svc *runtime.ServiceRuntime) *xfnproto.Result { l := svc.Log @@ -127,3 +108,22 @@ func DeployGarage(ctx context.Context, comp *vshnv1.VSHNGarage, svc *runtime.Ser return nil } + +// applyAllowedNamespaces decodes the JSON array through +// the comp-functions config key (`garageAllowedNamespaces`) and injects it +// into the vshngaragecluster chart values. +// An empty input leaves values untouched, for backwards compatibility. +// the chart simply skips the GarageReferenceGrant template. +func applyAllowedNamespaces(values map[string]any, raw string) error { + if raw == "" { + return nil + } + var allowed []string + if err := json.Unmarshal([]byte(raw), &allowed); err != nil { + return fmt.Errorf("cannot parse garageAllowedNamespaces %q: %w", raw, err) + } + if len(allowed) > 0 { + values["allowedNamespaces"] = allowed + } + return nil +}