Skip to content

Error when namespace set but not allowed or not set when required #196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions kustomize/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,19 @@ func (km *kManifest) namespace() string {
return km.id().namespace
}

func (km *kManifest) isNamespaced() (bool, error) {
m, err := km.mapping()
if err != nil {
return false, km.fmtErr(fmt.Errorf("api error: %s", err))
}

if m.Scope.Name() == k8smeta.RESTScopeNameNamespace {
return true, nil
}

return false, nil
}

func (km *kManifest) name() string {
return km.id().name
}
Expand All @@ -137,10 +150,21 @@ func (km *kManifest) id() (id kManifestId) {
func (km *kManifest) api() (api k8sdynamic.ResourceInterface, err error) {
gvr, err := km.gvr()
if err != nil {
return api, nil
return api, km.fmtErr(fmt.Errorf("api error: %s", err))
}

api = km.client.Resource(gvr)

isNamespaced, err := km.isNamespaced()
if err != nil {
return api, km.fmtErr(fmt.Errorf("api error: %s", err))
}

if isNamespaced {
api = km.client.Resource(gvr).Namespace(km.namespace())
}

return km.client.Resource(gvr).Namespace(km.namespace()), nil
return api, nil
}

func (km *kManifest) apiGet(opts k8smetav1.GetOptions) (resp *k8sunstructured.Unstructured, err error) {
Expand Down
29 changes: 21 additions & 8 deletions kustomize/resource_kustomization.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,28 @@ func kustomizationResourceDiff(ctx context.Context, d *schema.ResourceDiff, m in
}
setLastAppliedConfig(kmm, gzipLastAppliedConfig)

_, err = kmm.mappings()
if err != nil {
// if there are no mappings we can't dry-run
// this is for CRDs that do not exist yet
return nil
}

isNamespaced, err := kmm.isNamespaced()
if err != nil {
return logError(err)
}
if isNamespaced && kmm.namespace() == "" {
err = kmm.fmtErr(fmt.Errorf("is namespace scoped and must set metadata.namespace"))
return logError(err)
}
if !isNamespaced && kmm.namespace() != "" {
err = kmm.fmtErr(fmt.Errorf("is not namespace scoped but has metadata.namespace set"))
return logError(err)
}

if do.(string) == "" {
// diffing for create
_, err := kmm.mappings()
if err != nil {
// if there are no mappings we can't dry-run
// this is for CRDs that do not exist yet
return nil
}

_, err = kmm.apiCreate(k8smetav1.CreateOptions{DryRun: []string{k8smetav1.DryRunAll}})
if err != nil {
if k8serrors.IsAlreadyExists(err) {
Expand Down Expand Up @@ -334,7 +347,7 @@ func kustomizationResourceDelete(d *schema.ResourceData, m interface{}) error {
// the resource can't exist either
return nil
}
return logError(err)
return logError(km.fmtErr(err))
}

err = km.apiDelete(k8smetav1.DeleteOptions{})
Expand Down
54 changes: 54 additions & 0 deletions kustomize/resource_kustomization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,60 @@ resource "kustomization_resource" "ns" {
`
}

//
//
// Fail namespace not allowed
func TestAccResourceKustomization_failPlanInvalidNamespaceNotAllowed(t *testing.T) {

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
//
//
// Expect plan to fail due to namespace not allowed
{
Config: testAccResourceKustomizationConfig_failNamespaceNotAllowed("test_kustomizations/fail_namespace_not_allowed"),
ExpectError: regexp.MustCompile("Error: github.com/kbst/terraform-provider-kustomize/kustomize.kustomizationResourceDiff: \"rbac.authorization.k8s.io/ClusterRoleBinding/default/invalid\": is not namespace scoped but has metadata.namespace set"),
},
},
})
}

func testAccResourceKustomizationConfig_failNamespaceNotAllowed(path string) string {
return testAccDataSourceKustomizationConfig_basic(path) + `
resource "kustomization_resource" "crb" {
manifest = data.kustomization_build.test.manifests["rbac.authorization.k8s.io/ClusterRoleBinding/default/invalid"]
}
`
}

//
//
// Fail namespace required
func TestAccResourceKustomization_failNamespaceRequired(t *testing.T) {

resource.Test(t, resource.TestCase{
Providers: testAccProviders,
Steps: []resource.TestStep{
//
//
// Expect plan to fail due to missing namespace
{
Config: testAccResourceKustomizationConfig_failNamespaceRequired("test_kustomizations/fail_namespace_required"),
ExpectError: regexp.MustCompile("Error: github.com/kbst/terraform-provider-kustomize/kustomize.kustomizationResourceDiff: \"rbac.authorization.k8s.io/RoleBinding/_/invalid\": is namespace scoped and must set metadata.namespace"),
},
},
})
}

func testAccResourceKustomizationConfig_failNamespaceRequired(path string) string {
return testAccDataSourceKustomizationConfig_basic(path) + `
resource "kustomization_resource" "crb" {
manifest = data.kustomization_build.test.manifests["rbac.authorization.k8s.io/RoleBinding/_/invalid"]
}
`
}

//
//
// Fail plan invalid manifest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: invalid
# invalid not namespace scoped
namespace: default
subjects:
- kind: Group
name: admins
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- invalid_cluster_role_binding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: invalid
# invalid namespace scoped but no namespace
subjects:
- kind: Group
name: admins
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- invalid_role_binding.yaml