Skip to content

Commit

Permalink
Merge pull request #2495 from terraform-providers/f/kubernetes-rbac
Browse files Browse the repository at this point in the history
r/kubernetes_cluster: support for rbac without azuread / exporting the admin profile
  • Loading branch information
tombuildsstuff committed Dec 12, 2018
2 parents 22b0f87 + 40eaeb7 commit b21a4fe
Show file tree
Hide file tree
Showing 10 changed files with 443 additions and 91 deletions.
108 changes: 87 additions & 21 deletions azurerm/data_source_kubernetes_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,47 @@ func dataSourceArmKubernetesCluster() *schema.Resource {
Computed: true,
},

"kube_admin_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"host": {
Type: schema.TypeString,
Computed: true,
},
"username": {
Type: schema.TypeString,
Computed: true,
},
"password": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
"client_certificate": {
Type: schema.TypeString,
Computed: true,
},
"client_key": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
"cluster_ca_certificate": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"kube_admin_config_raw": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},

"kube_config": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -241,6 +282,10 @@ func dataSourceArmKubernetesCluster() *schema.Resource {
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"azure_active_directory": {
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -286,14 +331,13 @@ func dataSourceArmKubernetesCluster() *schema.Resource {
}

func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}) error {
kubernetesClustersClient := meta.(*ArmClient).kubernetesClustersClient
client := meta.(*ArmClient)
client := meta.(*ArmClient).kubernetesClustersClient
ctx := meta.(*ArmClient).StopContext

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

ctx := client.StopContext
resp, err := kubernetesClustersClient.Get(ctx, resourceGroup, name)
resp, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: Managed Kubernetes Cluster %q was not found in Resource Group %q", name, resourceGroup)
Expand All @@ -302,7 +346,7 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}
return fmt.Errorf("Error retrieving Managed Kubernetes Cluster %q (Resource Group %q): %+v", name, resourceGroup, err)
}

profile, err := kubernetesClustersClient.GetAccessProfile(ctx, resourceGroup, name, "clusterUser")
profile, err := client.GetAccessProfile(ctx, resourceGroup, name, "clusterUser")
if err != nil {
return fmt.Errorf("Error retrieving Access Profile for Managed Kubernetes Cluster %q (Resource Group %q): %+v", name, resourceGroup, err)
}
Expand Down Expand Up @@ -341,7 +385,7 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}
return fmt.Errorf("Error setting `network_profile`: %+v", err)
}

roleBasedAccessControl := flattenKubernetesClusterDataSourceRoleBasedAccessControl(props.AadProfile)
roleBasedAccessControl := flattenKubernetesClusterDataSourceRoleBasedAccessControl(props)
if err := d.Set("role_based_access_control", roleBasedAccessControl); err != nil {
return fmt.Errorf("Error setting `role_based_access_control`: %+v", err)
}
Expand All @@ -350,6 +394,23 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}
if err := d.Set("service_principal", servicePrincipal); err != nil {
return fmt.Errorf("Error setting `service_principal`: %+v", err)
}

// adminProfile is only available for RBAC enabled clusters with AAD
if props.AadProfile != nil {
adminProfile, err := client.GetAccessProfile(ctx, resourceGroup, name, "clusterAdmin")
if err != nil {
return fmt.Errorf("Error retrieving Admin Access Profile for Managed Kubernetes Cluster %q (Resource Group %q): %+v", name, resourceGroup, err)
}

adminKubeConfigRaw, adminKubeConfig := flattenKubernetesClusterAccessProfile(adminProfile)
d.Set("kube_admin_config_raw", adminKubeConfigRaw)
if err := d.Set("kube_admin_config", adminKubeConfig); err != nil {
return fmt.Errorf("Error setting `kube_admin_config`: %+v", err)
}
} else {
d.Set("kube_admin_config_raw", "")
d.Set("kube_admin_config", []interface{}{})
}
}

kubeConfigRaw, kubeConfig := flattenKubernetesClusterDataSourceAccessProfile(profile)
Expand All @@ -363,30 +424,35 @@ func dataSourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{}
return nil
}

func flattenKubernetesClusterDataSourceRoleBasedAccessControl(input *containerservice.ManagedClusterAADProfile) []interface{} {
if input == nil {
return []interface{}{}
func flattenKubernetesClusterDataSourceRoleBasedAccessControl(input *containerservice.ManagedClusterProperties) []interface{} {
rbacEnabled := false
if input.EnableRBAC != nil {
rbacEnabled = *input.EnableRBAC
}

profile := make(map[string]interface{})
results := make([]interface{}, 0)
if profile := input.AadProfile; profile != nil {
output := make(map[string]interface{})

if input.ClientAppID != nil {
profile["client_app_id"] = *input.ClientAppID
}
if profile.ClientAppID != nil {
output["client_app_id"] = *profile.ClientAppID
}

if input.ServerAppID != nil {
profile["server_app_id"] = *input.ServerAppID
}
if profile.ServerAppID != nil {
output["server_app_id"] = *profile.ServerAppID
}

if input.TenantID != nil {
profile["tenant_id"] = *input.TenantID
if profile.TenantID != nil {
output["tenant_id"] = *profile.TenantID
}

results = append(results, output)
}

return []interface{}{
map[string]interface{}{
"azure_active_directory": []interface{}{
profile,
},
"enabled": rbacEnabled,
"azure_active_directory": results,
},
}
}
Expand Down
53 changes: 49 additions & 4 deletions azurerm/data_source_kubernetes_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,50 @@ func TestAccDataSourceAzureRMKubernetesCluster_basic(t *testing.T) {
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKubernetesClusterExists(dataSourceName),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.#", "0"),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.0.enabled", "false"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_config.0.client_key"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_config.0.client_certificate"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_config.0.cluster_ca_certificate"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_config.0.host"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_config.0.username"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_config.0.password"),
resource.TestCheckResourceAttr(dataSourceName, "kube_admin_config.#", "0"),
resource.TestCheckResourceAttr(dataSourceName, "kube_admin_config_raw", ""),
),
},
},
})
}

func TestAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControl(t *testing.T) {
dataSourceName := "data.azurerm_kubernetes_cluster.test"
ri := acctest.RandInt()
location := testLocation()
clientId := os.Getenv("ARM_CLIENT_ID")
clientSecret := os.Getenv("ARM_CLIENT_SECRET")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMKubernetesClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControl(ri, location, clientId, clientSecret),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKubernetesClusterExists(dataSourceName),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.0.enabled", "true"),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.0.azure_active_directory.#", "0"),
resource.TestCheckResourceAttr(dataSourceName, "kube_admin_config.#", "0"),
resource.TestCheckResourceAttr(dataSourceName, "kube_admin_config_raw", ""),
),
},
},
})
}

func TestAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControlAAD(t *testing.T) {
dataSourceName := "data.azurerm_kubernetes_cluster.test"
ri := acctest.RandInt()
clientId := os.Getenv("ARM_CLIENT_ID")
Expand All @@ -53,14 +83,17 @@ func TestAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControl(t *testing
CheckDestroy: testCheckAzureRMKubernetesClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControl(ri, location, clientId, clientSecret, tenantId),
Config: testAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControlAAD(ri, location, clientId, clientSecret, tenantId),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKubernetesClusterExists(dataSourceName),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.0.enabled", "true"),
resource.TestCheckResourceAttr(dataSourceName, "role_based_access_control.0.azure_active_directory.#", "1"),
resource.TestCheckResourceAttrSet(dataSourceName, "role_based_access_control.0.azure_active_directory.0.client_app_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "role_based_access_control.0.azure_active_directory.0.server_app_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "role_based_access_control.0.azure_active_directory.0.tenant_id"),
resource.TestCheckResourceAttr(dataSourceName, "kube_admin_config.#", "1"),
resource.TestCheckResourceAttrSet(dataSourceName, "kube_admin_config_raw"),
),
},
},
Expand Down Expand Up @@ -273,8 +306,20 @@ data "azurerm_kubernetes_cluster" "test" {
`, r)
}

func testAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControl(rInt int, location, clientId, clientSecret, tenantId string) string {
resource := testAccAzureRMKubernetesCluster_roleBasedAccessControl(rInt, location, clientId, clientSecret, tenantId)
func testAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControl(rInt int, location, clientId, clientSecret string) string {
resource := testAccAzureRMKubernetesCluster_roleBasedAccessControl(rInt, location, clientId, clientSecret)
return fmt.Sprintf(`
%s
data "azurerm_kubernetes_cluster" "test" {
name = "${azurerm_kubernetes_cluster.test.name}"
resource_group_name = "${azurerm_kubernetes_cluster.test.resource_group_name}"
}
`, resource)
}

func testAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControlAAD(rInt int, location, clientId, clientSecret, tenantId string) string {
resource := testAccAzureRMKubernetesCluster_roleBasedAccessControlAAD(rInt, location, clientId, clientSecret, tenantId)
return fmt.Sprintf(`
%s
Expand Down
Loading

0 comments on commit b21a4fe

Please sign in to comment.