-
Notifications
You must be signed in to change notification settings - Fork 958
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6bbc5bc
commit 27b29cc
Showing
7 changed files
with
584 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package kubernetes | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"k8s.io/apimachinery/pkg/api/errors" | ||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
pkgApi "k8s.io/apimachinery/pkg/types" | ||
api "k8s.io/kubernetes/pkg/apis/rbac/v1" | ||
kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||
) | ||
|
||
func resourceKubernetesClusterRoleBinding() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceKubernetesClusterRoleBindingCreate, | ||
Read: resourceKubernetesClusterRoleBindingRead, | ||
Exists: resourceKubernetesClusterRoleBindingExists, | ||
Update: resourceKubernetesClusterRoleBindingUpdate, | ||
Delete: resourceKubernetesClusterRoleBindingDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"metadata": metadataSchema("clusterRoleBinding", false), | ||
"role_ref": { | ||
Type: schema.TypeMap, | ||
Description: "RoleRef references the Cluster Role for this binding", | ||
Required: true, | ||
ForceNew: true, | ||
Elem: &schema.Resource{ | ||
Schema: rbacRoleRefSchema("ClusterRole"), | ||
}, | ||
}, | ||
"subject": { | ||
Type: schema.TypeList, | ||
Description: "Subjects defines the entities to bind a ClusterRole to.", | ||
Required: true, | ||
MinItems: 1, | ||
Elem: &schema.Resource{ | ||
Schema: rbacSubjectSchema(), | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceKubernetesClusterRoleBindingCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*kubernetes.Clientset) | ||
|
||
metadata := expandMetadata(d.Get("metadata").([]interface{})) | ||
binding := &api.ClusterRoleBinding{ | ||
ObjectMeta: metadata, | ||
RoleRef: expandRBACRoleRef(d.Get("role_ref").(interface{})), | ||
Subjects: expandRBACSubjects(d.Get("subject").([]interface{})), | ||
} | ||
log.Printf("[INFO] Creating new ClusterRoleBinding: %#v", binding) | ||
binding, err := conn.Rbac().ClusterRoleBindings().Create(binding) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
log.Printf("[INFO] Submitted new ClusterRoleBinding: %#v", binding) | ||
d.SetId(metadata.Name) | ||
|
||
return resourceKubernetesClusterRoleBindingRead(d, meta) | ||
} | ||
|
||
func resourceKubernetesClusterRoleBindingRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*kubernetes.Clientset) | ||
|
||
name := d.Id() | ||
log.Printf("[INFO] Reading ClusterRoleBinding %s", name) | ||
binding, err := conn.Rbac().ClusterRoleBindings().Get(name, meta_v1.GetOptions{}) | ||
if err != nil { | ||
log.Printf("[DEBUG] Received error: %#v", err) | ||
return err | ||
} | ||
|
||
log.Printf("[INFO] Received ClusterRoleBinding: %#v", binding) | ||
err = d.Set("metadata", flattenMetadata(binding.ObjectMeta)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
flattenedRef := flattenRBACRoleRef(binding.RoleRef) | ||
log.Printf("[DEBUG] Flattened ClusterRoleBinding roleRef: %#v", flattenedRef) | ||
err = d.Set("role_ref", flattenedRef) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
flattenedSubjects := flattenRBACSubjects(binding.Subjects) | ||
log.Printf("[DEBUG] Flattened ClusterRoleBinding subjects: %#v", flattenedSubjects) | ||
err = d.Set("subject", flattenedSubjects) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceKubernetesClusterRoleBindingUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*kubernetes.Clientset) | ||
|
||
name := d.Id() | ||
|
||
ops := patchMetadata("metadata.0.", "/metadata/", d) | ||
if d.HasChange("subject") { | ||
diffOps := patchRbacSubject(d) | ||
ops = append(ops, diffOps...) | ||
} | ||
data, err := ops.MarshalJSON() | ||
if err != nil { | ||
return fmt.Errorf("Failed to marshal update operations: %s", err) | ||
} | ||
log.Printf("[INFO] Updating ClusterRoleBinding %q: %v", name, string(data)) | ||
out, err := conn.Rbac().ClusterRoleBindings().Patch(name, pkgApi.JSONPatchType, data) | ||
if err != nil { | ||
return fmt.Errorf("Failed to update ClusterRoleBinding: %s", err) | ||
} | ||
log.Printf("[INFO] Submitted updated ClusterRoleBinding: %#v", out) | ||
d.SetId(out.ObjectMeta.Name) | ||
|
||
return resourceKubernetesClusterRoleBindingRead(d, meta) | ||
} | ||
|
||
func resourceKubernetesClusterRoleBindingDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*kubernetes.Clientset) | ||
|
||
name := d.Id() | ||
log.Printf("[INFO] Deleting ClusterRoleBinding: %#v", name) | ||
err := conn.Rbac().ClusterRoleBindings().Delete(name, &meta_v1.DeleteOptions{}) | ||
if err != nil { | ||
return err | ||
} | ||
log.Printf("[INFO] ClusterRoleBinding %s deleted", name) | ||
|
||
d.SetId("") | ||
return nil | ||
} | ||
|
||
func resourceKubernetesClusterRoleBindingExists(d *schema.ResourceData, meta interface{}) (bool, error) { | ||
conn := meta.(*kubernetes.Clientset) | ||
|
||
name := d.Id() | ||
log.Printf("[INFO] Checking ClusterRoleBinding %s", name) | ||
_, err := conn.Rbac().ClusterRoleBindings().Get(name, meta_v1.GetOptions{}) | ||
if err != nil { | ||
if statusErr, ok := err.(*errors.StatusError); ok && statusErr.ErrStatus.Code == 404 { | ||
return false, nil | ||
} | ||
log.Printf("[DEBUG] Received error: %#v", err) | ||
} | ||
return true, err | ||
} |
179 changes: 179 additions & 0 deletions
179
kubernetes/resource_kubernetes_cluster_role_binding_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
package kubernetes | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/acctest" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
api "k8s.io/kubernetes/pkg/apis/rbac/v1" | ||
kubernetes "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||
) | ||
|
||
func TestAccKubernetesClusterRoleBinding(t *testing.T) { | ||
var conf api.ClusterRoleBinding | ||
name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
IDRefreshName: "kubernetes_cluster_role_binding.test", | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckKubernetesClusterRoleBindingDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccKubernetesClusterRoleBindingConfig_basic(name), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
testAccCheckKubernetesClusterRoleBindingExists("kubernetes_cluster_role_binding.test", &conf), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "metadata.0.name", name), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.generation"), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.resource_version"), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.self_link"), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.uid"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.%", "3"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.api_group", "rbac.authorization.k8s.io"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.kind", "ClusterRole"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.name", "cluster-admin"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.#", "1"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.0.api_group", "rbac.authorization.k8s.io"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.0.name", "notauser"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.0.kind", "User"), | ||
), | ||
}, | ||
{ | ||
Config: testAccKubernetesClusterRoleBindingConfig_modified(name), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
testAccCheckKubernetesClusterRoleBindingExists("kubernetes_cluster_role_binding.test", &conf), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "metadata.0.name", name), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.generation"), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.resource_version"), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.self_link"), | ||
resource.TestCheckResourceAttrSet("kubernetes_cluster_role_binding.test", "metadata.0.uid"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.%", "3"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.api_group", "rbac.authorization.k8s.io"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.kind", "ClusterRole"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "role_ref.name", "cluster-admin"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.#", "3"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.0.api_group", "rbac.authorization.k8s.io"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.0.name", "notauser"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.0.kind", "User"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.1.namespace", "kube-system"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.1.name", "default"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.1.kind", "ServiceAccount"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.2.api_group", "rbac.authorization.k8s.io"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.2.name", "system:masters"), | ||
resource.TestCheckResourceAttr("kubernetes_cluster_role_binding.test", "subject.2.kind", "Group"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccKubernetesClusterRoleBinding_importBasic(t *testing.T) { | ||
resourceName := "kubernetes_cluster_role_binding.test" | ||
name := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckKubernetesClusterRoleBindingDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccKubernetesClusterRoleBindingConfig_basic(name), | ||
}, | ||
|
||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckKubernetesClusterRoleBindingDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*kubernetes.Clientset) | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "kubernetes_cluster_role_binding" { | ||
continue | ||
} | ||
name := rs.Primary.ID | ||
resp, err := conn.Rbac().ClusterRoleBindings().Get(name, meta_v1.GetOptions{}) | ||
if err == nil { | ||
if resp.Name == rs.Primary.ID { | ||
return fmt.Errorf("ClusterRoleBinding still exists: %s", rs.Primary.ID) | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckKubernetesClusterRoleBindingExists(n string, obj *api.ClusterRoleBinding) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", n) | ||
} | ||
|
||
conn := testAccProvider.Meta().(*kubernetes.Clientset) | ||
name := rs.Primary.ID | ||
resp, err := conn.Rbac().ClusterRoleBindings().Get(name, meta_v1.GetOptions{}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*obj = *resp | ||
return nil | ||
} | ||
} | ||
|
||
func testAccKubernetesClusterRoleBindingConfig_basic(name string) string { | ||
return fmt.Sprintf(` | ||
resource "kubernetes_cluster_role_binding" "test" { | ||
metadata { | ||
name = "%s" | ||
} | ||
role_ref { | ||
api_group = "rbac.authorization.k8s.io" | ||
kind = "ClusterRole" | ||
name = "cluster-admin" | ||
} | ||
subject { | ||
kind = "User" | ||
name = "notauser" | ||
api_group = "rbac.authorization.k8s.io" | ||
} | ||
}`, name) | ||
} | ||
|
||
func testAccKubernetesClusterRoleBindingConfig_modified(name string) string { | ||
return fmt.Sprintf(` | ||
resource "kubernetes_cluster_role_binding" "test" { | ||
metadata { | ||
name = "%s" | ||
} | ||
role_ref { | ||
api_group = "rbac.authorization.k8s.io" | ||
kind = "ClusterRole" | ||
name = "cluster-admin" | ||
} | ||
subject { | ||
kind = "User" | ||
name = "notauser" | ||
api_group = "rbac.authorization.k8s.io" | ||
} | ||
subject { | ||
kind = "ServiceAccount" | ||
name = "default" | ||
namespace = "kube-system" | ||
} | ||
subject { | ||
kind = "Group" | ||
name = "system:masters" | ||
api_group = "rbac.authorization.k8s.io" | ||
} | ||
}`, name) | ||
} |
Oops, something went wrong.