Skip to content

Commit

Permalink
r/kubernetes_cluster: support for rbac without aad
Browse files Browse the repository at this point in the history
Fixes #2345
  • Loading branch information
tombuildsstuff committed Dec 12, 2018
1 parent 8f3bc74 commit c9f1853
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 67 deletions.
41 changes: 25 additions & 16 deletions azurerm/data_source_kubernetes_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,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 @@ -341,7 +345,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 @@ -363,30 +367,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
47 changes: 43 additions & 4 deletions azurerm/data_source_kubernetes_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ 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"),
Expand All @@ -40,6 +41,31 @@ func TestAccDataSourceAzureRMKubernetesCluster_basic(t *testing.T) {
}

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"),
),
},
},
})
}

func TestAccDataSourceAzureRMKubernetesCluster_roleBasedAccessControlAAD(t *testing.T) {
dataSourceName := "data.azurerm_kubernetes_cluster.test"
ri := acctest.RandInt()
clientId := os.Getenv("ARM_CLIENT_ID")
Expand All @@ -53,10 +79,11 @@ 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"),
Expand Down Expand Up @@ -273,8 +300,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
82 changes: 47 additions & 35 deletions azurerm/resource_arm_kubernetes_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,19 @@ func resourceArmKubernetesCluster() *schema.Resource {
"role_based_access_control": {
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Required: true,
ForceNew: true,
},
"azure_active_directory": {
Type: schema.TypeList,
Required: true,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Expand Down Expand Up @@ -450,8 +456,7 @@ func resourceArmKubernetesClusterCreateUpdate(d *schema.ResourceData, meta inter
}

rbacRaw := d.Get("role_based_access_control").([]interface{})
azureADProfile := expandKubernetesClusterRoleBasedAccessControl(rbacRaw, tenantId)
roleBasedAccessControlEnabled := azureADProfile != nil
rbacEnabled, azureADProfile := expandKubernetesClusterRoleBasedAccessControl(rbacRaw, tenantId)

parameters := containerservice.ManagedCluster{
Name: &name,
Expand All @@ -461,7 +466,7 @@ func resourceArmKubernetesClusterCreateUpdate(d *schema.ResourceData, meta inter
AddonProfiles: addonProfiles,
AgentPoolProfiles: &agentProfiles,
DNSPrefix: utils.String(dnsPrefix),
EnableRBAC: utils.Bool(roleBasedAccessControlEnabled),
EnableRBAC: utils.Bool(rbacEnabled),
KubernetesVersion: utils.String(kubernetesVersion),
LinuxProfile: linuxProfile,
NetworkProfile: networkProfile,
Expand Down Expand Up @@ -552,7 +557,7 @@ func resourceArmKubernetesClusterRead(d *schema.ResourceData, meta interface{})
return fmt.Errorf("Error setting `network_profile`: %+v", err)
}

roleBasedAccessControl := flattenKubernetesClusterRoleBasedAccessControl(props.AadProfile, d)
roleBasedAccessControl := flattenKubernetesClusterRoleBasedAccessControl(props, d)
if err := d.Set("role_based_access_control", roleBasedAccessControl); err != nil {
return fmt.Errorf("Error setting `role_based_access_control`: %+v", err)
}
Expand Down Expand Up @@ -914,13 +919,15 @@ func flattenKubernetesClusterNetworkProfile(profile *containerservice.NetworkPro
return []interface{}{values}
}

func expandKubernetesClusterRoleBasedAccessControl(input []interface{}, providerTenantId string) *containerservice.ManagedClusterAADProfile {
func expandKubernetesClusterRoleBasedAccessControl(input []interface{}, providerTenantId string) (bool, *containerservice.ManagedClusterAADProfile) {
if len(input) == 0 {
return nil
return false, nil
}

val := input[0].(map[string]interface{})

rbacEnabled := val["enabled"].(bool)

azureADsRaw := val["azure_active_directory"].([]interface{})
azureAdRaw := azureADsRaw[0].(map[string]interface{})

Expand All @@ -933,54 +940,59 @@ func expandKubernetesClusterRoleBasedAccessControl(input []interface{}, provider
tenantId = providerTenantId
}

return &containerservice.ManagedClusterAADProfile{
return rbacEnabled, &containerservice.ManagedClusterAADProfile{
ClientAppID: utils.String(clientAppId),
ServerAppID: utils.String(serverAppId),
ServerAppSecret: utils.String(serverAppSecret),
TenantID: utils.String(tenantId),
}
}

func flattenKubernetesClusterRoleBasedAccessControl(input *containerservice.ManagedClusterAADProfile, d *schema.ResourceData) []interface{} {
if input == nil {
return []interface{}{}
func flattenKubernetesClusterRoleBasedAccessControl(input *containerservice.ManagedClusterProperties, d *schema.ResourceData) []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
}

// since input.ServerAppSecret isn't returned we're pulling this out of the existing state (which won't work for Imports)
// role_based_access_control.0.azure_active_directory.0.server_app_secret
if existing, ok := d.GetOk("role_based_access_control"); ok {
rbacRawVals := existing.([]interface{})
if len(rbacRawVals) > 0 {
rbacRawVal := rbacRawVals[0].(map[string]interface{})
if azureADVals, ok := rbacRawVal["azure_active_directory"].([]interface{}); ok && len(azureADVals) > 0 {
azureADVal := azureADVals[0].(map[string]interface{})
v := azureADVal["server_app_secret"]
if v != nil {
profile["server_app_secret"] = v.(string)
// since input.ServerAppSecret isn't returned we're pulling this out of the existing state (which won't work for Imports)
// role_based_access_control.0.azure_active_directory.0.server_app_secret
if existing, ok := d.GetOk("role_based_access_control"); ok {
rbacRawVals := existing.([]interface{})
if len(rbacRawVals) > 0 {
rbacRawVal := rbacRawVals[0].(map[string]interface{})
if azureADVals, ok := rbacRawVal["azure_active_directory"].([]interface{}); ok && len(azureADVals) > 0 {
azureADVal := azureADVals[0].(map[string]interface{})
v := azureADVal["server_app_secret"]
if v != nil {
output["server_app_secret"] = v.(string)
}
}
}
}
}

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
Loading

0 comments on commit c9f1853

Please sign in to comment.