From 39b117e6d79ace1d5052cfd1e0c1c732e1a3830f Mon Sep 17 00:00:00 2001 From: Flavio Briz Date: Thu, 6 Feb 2025 18:37:10 +0000 Subject: [PATCH 1/2] fix(kubeconfig): Enforces kubernetes context with helm release namespace --- helm/kubeconfig.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helm/kubeconfig.go b/helm/kubeconfig.go index 137fa3b16..78753a9c9 100644 --- a/helm/kubeconfig.go +++ b/helm/kubeconfig.go @@ -143,6 +143,8 @@ func (m *Meta) NewKubeConfig(ctx context.Context, namespace string) (*KubeConfig } if !kubernetesConfig.ConfigContextCluster.IsNull() { overrides.Context.Cluster = kubernetesConfig.ConfigContextCluster.ValueString() + // Enforces configured release namespace + overrides.Context.Namespace = namespace } } From 6ea9158ea568abab2aff76cbafcb589bb6cfb391 Mon Sep 17 00:00:00 2001 From: Flavio Briz Date: Sat, 12 Apr 2025 14:59:25 +0100 Subject: [PATCH 2/2] test(resource_helm_release_test): resources namespace validation Checks if all resources are deployed to the correct namespace. Only Resources bound to specific namespaces are checked, the rest is ignored. --- go.mod | 4 +-- helm/resource_helm_release_test.go | 50 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 95a8ed8c6..da74d1f5d 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,11 @@ go 1.22.0 toolchain go1.22.3 require ( - github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 github.com/hashicorp/terraform-plugin-docs v0.19.4 github.com/hashicorp/terraform-plugin-framework v1.11.0 github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 github.com/hashicorp/terraform-plugin-go v0.23.0 github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 github.com/hashicorp/terraform-plugin-testing v1.10.0 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 @@ -93,6 +91,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.6.0 // indirect @@ -104,6 +103,7 @@ require ( github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect github.com/hashicorp/terraform-json v0.22.1 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect diff --git a/helm/resource_helm_release_test.go b/helm/resource_helm_release_test.go index 05a664f45..78b978f7e 100644 --- a/helm/resource_helm_release_test.go +++ b/helm/resource_helm_release_test.go @@ -27,6 +27,9 @@ import ( "helm.sh/helm/v3/pkg/release" "helm.sh/helm/v3/pkg/releaseutil" "helm.sh/helm/v3/pkg/repo" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" ) func TestAccResourceRelease_basic(t *testing.T) { @@ -1181,6 +1184,50 @@ func testAccCheckHelmReleaseDependencyUpdate(namespace string, name string, expe } } +func testAccCheckHelmReleaseResourceNamespace(namespace string, name string) resource.TestCheckFunc { + // Ensures all resources in a release are in the same requested namespace. Including dependency resources. + + return func(s *terraform.State) error { + actionConfig := &action.Configuration{} + if err := actionConfig.Init(kube.GetConfig(os.Getenv("KUBE_CONFIG_PATH"), "", namespace), namespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) { + log.Printf(fmt.Sprintf(format, v...)) + }); err != nil { + return err + } + + status := action.NewStatus(actionConfig) + status.ShowResources = true + + res, err := status.Run(name) + + if res == nil { + return fmt.Errorf("release %q not found", name) + } + + if err != nil { + return err + } + + for _, resources := range res.Info.Resources { + for _, resource := range resources { + innerObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(resource) + if err != nil { + return fmt.Errorf("unable to decode runtime object %s, with error: %s", resource, err) + } + + u := unstructured.Unstructured{Object: innerObj} + + // Skip check for resources that are not bound to namespaces + if ns := u.GetNamespace(); ns != "" && ns != namespace { + return fmt.Errorf("expected namespace %s, but got %v", namespace, ns) + } + } + } + + return nil + } +} + func testAccCheckHelmReleaseDestroy(namespace string) resource.TestCheckFunc { return func(s *terraform.State) error { log.Printf("testMeta before checking: %+v\n", testMeta) @@ -1358,6 +1405,7 @@ func TestAccResourceRelease_dependency(t *testing.T) { { Config: testAccHelmReleaseConfigDependency(testResourceName, namespace, name, true), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckHelmReleaseResourceNamespace(namespace, name), resource.TestCheckResourceAttr("helm_release.test", "metadata.revision", "1"), resource.TestCheckResourceAttr("helm_release.test", "status", release.StatusDeployed.String()), resource.TestCheckResourceAttr("helm_release.test", "dependency_update", "true"), @@ -1371,6 +1419,7 @@ func TestAccResourceRelease_dependency(t *testing.T) { }, Config: testAccHelmReleaseConfigDependencyUpdate(testResourceName, namespace, name, true), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckHelmReleaseResourceNamespace(namespace, name), testAccCheckHelmReleaseDependencyUpdate(namespace, name, 9), resource.TestCheckResourceAttr("helm_release.test", "metadata.revision", "2"), resource.TestCheckResourceAttr("helm_release.test", "status", release.StatusDeployed.String()), @@ -1385,6 +1434,7 @@ func TestAccResourceRelease_dependency(t *testing.T) { }, Config: testAccHelmReleaseConfigDependencyUpdateWithLint(testResourceName, namespace, name, true), Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckHelmReleaseResourceNamespace(namespace, name), resource.TestCheckResourceAttr("helm_release.test", "metadata.revision", "3"), resource.TestCheckResourceAttr("helm_release.test", "status", release.StatusDeployed.String()), resource.TestCheckResourceAttr("helm_release.test", "dependency_update", "true"),