Skip to content

Commit 4a3c075

Browse files
fix cluster role binding namespace handling
1 parent ec878df commit 4a3c075

File tree

3 files changed

+110
-6
lines changed

3 files changed

+110
-6
lines changed

kubernetes/resource_kubernetes_cluster_role_binding_v1_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,90 @@ func TestAccKubernetesClusterRoleBindingV1_UpdatePatchOperationsOrderWithRemoval
321321
})
322322
}
323323

324+
func TestAccKubernetesClusterRoleBindingV1_namespaceHandling(t *testing.T) {
325+
var conf rbacv1.ClusterRoleBinding
326+
name := fmt.Sprintf("tf-acc-test:%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
327+
resourceName := "kubernetes_cluster_role_binding_v1.test"
328+
329+
resource.ParallelTest(t, resource.TestCase{
330+
PreCheck: func() { testAccPreCheck(t) },
331+
IDRefreshName: resourceName,
332+
IDRefreshIgnore: []string{"metadata.0.resource_version"},
333+
ProviderFactories: testAccProviderFactories,
334+
CheckDestroy: testAccCheckKubernetesClusterRoleBindingV1Destroy,
335+
Steps: []resource.TestStep{
336+
{
337+
Config: testAccKubernetesClusterRoleBindingV1Config_namespaceHandling(name),
338+
Check: resource.ComposeAggregateTestCheckFunc(
339+
testAccCheckKubernetesClusterRoleBindingV1Exists(resourceName, &conf),
340+
resource.TestCheckResourceAttr(resourceName, "metadata.0.name", name),
341+
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.generation"),
342+
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.resource_version"),
343+
resource.TestCheckResourceAttrSet(resourceName, "metadata.0.uid"),
344+
resource.TestCheckResourceAttr(resourceName, "role_ref.#", "1"),
345+
resource.TestCheckResourceAttr(resourceName, "role_ref.0.api_group", "rbac.authorization.k8s.io"),
346+
resource.TestCheckResourceAttr(resourceName, "role_ref.0.kind", "ClusterRole"),
347+
resource.TestCheckResourceAttr(resourceName, "role_ref.0.name", "cluster-admin"),
348+
resource.TestCheckResourceAttr(resourceName, "subject.#", "3"),
349+
// Checking Group subject
350+
resource.TestCheckResourceAttr(resourceName, "subject.0.api_group", "rbac.authorization.k8s.io"),
351+
resource.TestCheckResourceAttr(resourceName, "subject.0.kind", "Group"),
352+
resource.TestCheckResourceAttr(resourceName, "subject.0.name", "testgroup"),
353+
resource.TestCheckResourceAttr(resourceName, "subject.0.namespace", ""),
354+
// Checking User subject
355+
resource.TestCheckResourceAttr(resourceName, "subject.1.api_group", "rbac.authorization.k8s.io"),
356+
resource.TestCheckResourceAttr(resourceName, "subject.1.kind", "User"),
357+
resource.TestCheckResourceAttr(resourceName, "subject.1.name", "testuser"),
358+
resource.TestCheckResourceAttr(resourceName, "subject.1.namespace", ""),
359+
// Checking ServiceAccount subject
360+
resource.TestCheckResourceAttr(resourceName, "subject.2.api_group", ""),
361+
resource.TestCheckResourceAttr(resourceName, "subject.2.kind", "ServiceAccount"),
362+
resource.TestCheckResourceAttr(resourceName, "subject.2.name", "default"),
363+
resource.TestCheckResourceAttr(resourceName, "subject.2.namespace", "default"),
364+
),
365+
},
366+
},
367+
})
368+
}
369+
370+
func testAccKubernetesClusterRoleBindingV1Config_namespaceHandling(name string) string {
371+
return fmt.Sprintf(`resource "kubernetes_cluster_role_binding_v1" "test" {
372+
metadata {
373+
name = "%s"
374+
}
375+
376+
role_ref {
377+
api_group = "rbac.authorization.k8s.io"
378+
kind = "ClusterRole"
379+
name = "cluster-admin"
380+
}
381+
382+
# Group subject with namespace explicitly set to ""
383+
subject {
384+
kind = "Group"
385+
name = "testgroup"
386+
api_group = "rbac.authorization.k8s.io"
387+
namespace = ""
388+
}
389+
390+
# User subject with namespace explicitly set to ""
391+
subject {
392+
kind = "User"
393+
name = "testuser"
394+
api_group = "rbac.authorization.k8s.io"
395+
namespace = ""
396+
}
397+
398+
# ServiceAccount subject with no namespace specified
399+
subject {
400+
kind = "ServiceAccount"
401+
name = "default"
402+
api_group = ""
403+
}
404+
}
405+
`, name)
406+
}
407+
324408
func testAccCheckKubernetesClusterRoleBindingV1Destroy(s *terraform.State) error {
325409
conn, err := testAccProvider.Meta().(KubeClientsets).MainClientset()
326410

kubernetes/schema_rbac.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ func rbacSubjectSchema() map[string]*schema.Schema {
8888
Type: schema.TypeString,
8989
Description: "The Namespace of the subject resource.",
9090
Optional: true,
91-
Default: "default",
91+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
92+
// Suppress diff if namespace is "default" or omitted
93+
return (old == "" && new == "default") || (old == "default" && new == "")
94+
},
9295
},
9396
}
9497
}

kubernetes/structures_rbac.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,23 @@ func expandRBACSubjects(in []interface{}) []api.Subject {
4242
subject.APIGroup = v.(string)
4343
}
4444
if v, ok := m["kind"].(string); ok {
45-
subject.Kind = string(v)
45+
subject.Kind = v
4646
}
4747
if v, ok := m["name"]; ok {
4848
subject.Name = v.(string)
4949
}
50-
if v, ok := m["namespace"]; ok {
51-
subject.Namespace = v.(string)
50+
51+
// Handle namespace logic
52+
if subject.Kind == "Group" || subject.Kind == "User" {
53+
// Exclude namespace for Group and User kinds
54+
} else {
55+
if v, ok := m["namespace"]; ok && v != "" {
56+
// We are using the provided namespace if it is set
57+
subject.Namespace = v.(string)
58+
} else {
59+
//Due to it not being Group / Kind and namespace not being set, we Default to "default"
60+
subject.Namespace = "default"
61+
}
5262
}
5363
subjects = append(subjects, subject)
5464
}
@@ -121,8 +131,15 @@ func flattenRBACSubjects(in []api.Subject) []interface{} {
121131
}
122132
m["kind"] = n.Kind
123133
m["name"] = n.Name
124-
if n.Namespace != "" {
125-
m["namespace"] = n.Namespace
134+
135+
if n.Kind == "Group" || n.Kind == "User" {
136+
m["namespace"] = ""
137+
} else {
138+
if n.Namespace == "" {
139+
m["namespace"] = "default"
140+
} else {
141+
m["namespace"] = n.Namespace
142+
}
126143
}
127144
att = append(att, m)
128145
}

0 commit comments

Comments
 (0)