Skip to content

Commit

Permalink
azurerm_kubernetes_cluster - Use list API instead of GetAccessProfi…
Browse files Browse the repository at this point in the history
…le (#20927)

* use list API instead of GetAccessProfile to fix #20843

* change GetAccessProfile to List Credentials API for kubernetes cluster resource

* remove unused functions
  • Loading branch information
lonegunmanb committed Mar 20, 2023
1 parent b67bffa commit bd2e923
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 110 deletions.
67 changes: 35 additions & 32 deletions internal/services/containers/kubernetes_cluster_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -688,15 +688,14 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}
return fmt.Errorf("retrieving %s: %+v", id, err)
}

profileId := managedclusters.NewAccessProfileID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string), "clusterUser")
profile, err := client.GetAccessProfile(ctx, profileId)
credentials, err := client.ListClusterUserCredentials(ctx, id, managedclusters.ListClusterUserCredentialsOperationOptions{})
if err != nil {
return fmt.Errorf("retrieving Access Profile for %s: %+v", id, err)
return fmt.Errorf("retrieving User Credentials for %s: %+v", id, err)
}
if profile.Model == nil {
return fmt.Errorf("retrieving Access Profile for %s: payload is empty", id)
if credentials.Model == nil {
return fmt.Errorf("retrieving User Credentials for %s: payload is empty", id)
}
profileModel := profile.Model
credentialsModel := credentials.Model

d.SetId(id.ID())
if model := resp.Model; model != nil {
Expand Down Expand Up @@ -822,14 +821,13 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}

// adminProfile is only available for RBAC enabled clusters with AAD and without local accounts disabled
if props.AadProfile != nil && (props.DisableLocalAccounts == nil || !*props.DisableLocalAccounts) {
profileId := managedclusters.NewAccessProfileID(subscriptionId, id.ResourceGroupName, id.ManagedClusterName, "clusterAdmin")
adminProfile, err := client.GetAccessProfile(ctx, profileId)
adminCredentials, err := client.ListClusterAdminCredentials(ctx, id, managedclusters.ListClusterAdminCredentialsOperationOptions{})
if err != nil {
return fmt.Errorf("retrieving Admin Access Profile for %s: %+v", id, err)
return fmt.Errorf("retrieving Admin Credentials for %s: %+v", id, err)
}

if adminProfileModel := adminProfile.Model; adminProfileModel != nil {
adminKubeConfigRaw, adminKubeConfig := flattenKubernetesClusterAccessProfile(*adminProfileModel)
if adminCredentialModel := adminCredentials.Model; adminCredentialModel != nil {
adminKubeConfigRaw, adminKubeConfig := flattenKubernetesClusterCredentials(*adminCredentialModel, "clusterAdmin")
d.Set("kube_admin_config_raw", adminKubeConfigRaw)
if err := d.Set("kube_admin_config", adminKubeConfig); err != nil {
return fmt.Errorf("setting `kube_admin_config`: %+v", err)
Expand All @@ -850,7 +848,7 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}
return fmt.Errorf("setting `identity`: %+v", err)
}

kubeConfigRaw, kubeConfig := flattenKubernetesClusterDataSourceAccessProfile(*profileModel)
kubeConfigRaw, kubeConfig := flattenKubernetesClusterCredentials(*credentialsModel, "clusterUser")
d.Set("kube_config_raw", kubeConfigRaw)
if err := d.Set("kube_config", kubeConfig); err != nil {
return fmt.Errorf("setting `kube_config`: %+v", err)
Expand Down Expand Up @@ -926,36 +924,41 @@ func flattenKubernetesClusterDataSourceStorageProfile(input *managedclusters.Man
return storageProfile
}

func flattenKubernetesClusterDataSourceAccessProfile(profile managedclusters.ManagedClusterAccessProfile) (*string, []interface{}) {
if profile.Properties == nil {
func flattenKubernetesClusterCredentials(model managedclusters.CredentialResults, configName string) (*string, []interface{}) {
if model.Kubeconfigs == nil || len(*model.Kubeconfigs) < 1 {
return nil, []interface{}{}
}

if kubeConfigRaw := profile.Properties.KubeConfig; kubeConfigRaw != nil {
rawConfig := *kubeConfigRaw
if base64IsEncoded(*kubeConfigRaw) {
rawConfig = base64Decode(*kubeConfigRaw)
for _, c := range *model.Kubeconfigs {
if c.Name == nil || *c.Name != configName {
continue
}
if kubeConfigRaw := c.Value; kubeConfigRaw != nil {
rawConfig := *kubeConfigRaw
if base64IsEncoded(*kubeConfigRaw) {
rawConfig = base64Decode(*kubeConfigRaw)
}

var flattenedKubeConfig []interface{}
var flattenedKubeConfig []interface{}

if strings.Contains(rawConfig, "apiserver-id:") || strings.Contains(rawConfig, "exec") {
kubeConfigAAD, err := kubernetes.ParseKubeConfigAAD(rawConfig)
if err != nil {
return utils.String(rawConfig), []interface{}{}
}
if strings.Contains(rawConfig, "apiserver-id:") || strings.Contains(rawConfig, "exec") {
kubeConfigAAD, err := kubernetes.ParseKubeConfigAAD(rawConfig)
if err != nil {
return utils.String(rawConfig), []interface{}{}
}

flattenedKubeConfig = flattenKubernetesClusterDataSourceKubeConfigAAD(*kubeConfigAAD)
} else {
kubeConfig, err := kubernetes.ParseKubeConfig(rawConfig)
if err != nil {
return utils.String(rawConfig), []interface{}{}
flattenedKubeConfig = flattenKubernetesClusterDataSourceKubeConfigAAD(*kubeConfigAAD)
} else {
kubeConfig, err := kubernetes.ParseKubeConfig(rawConfig)
if err != nil {
return utils.String(rawConfig), []interface{}{}
}

flattenedKubeConfig = flattenKubernetesClusterDataSourceKubeConfig(*kubeConfig)
}

flattenedKubeConfig = flattenKubernetesClusterDataSourceKubeConfig(*kubeConfig)
return utils.String(rawConfig), flattenedKubeConfig
}

return utils.String(rawConfig), flattenedKubeConfig
}

return nil, []interface{}{}
Expand Down
89 changes: 11 additions & 78 deletions internal/services/containers/kubernetes_cluster_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/features"
computeValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/kubernetes"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/migration"
containerValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/validate"
keyVaultClient "github.com/hashicorp/terraform-provider-azurerm/internal/services/keyvault/client"
Expand Down Expand Up @@ -2145,10 +2144,12 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{})
return fmt.Errorf("retrieving %s: no payload delivered", *id)
}

accessProfileId := managedclusters.NewAccessProfileID(id.SubscriptionId, id.ResourceGroupName, id.ManagedClusterName, "clusterUser")
profile, err := client.GetAccessProfile(ctx, accessProfileId)
credentials, err := client.ListClusterUserCredentials(ctx, *id, managedclusters.ListClusterUserCredentialsOperationOptions{})
if err != nil {
return fmt.Errorf("retrieving Access Profile for %s: %+v", *id, err)
return fmt.Errorf("retrieving User Credentials for %s: %+v", id, err)
}
if credentials.Model == nil {
return fmt.Errorf("retrieving User Credentials for %s: payload is empty", id)
}

d.Set("name", id.ManagedClusterName)
Expand Down Expand Up @@ -2365,16 +2366,14 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{})

// adminProfile is only available for RBAC enabled clusters with AAD and local account is not disabled
if props.AadProfile != nil && (props.DisableLocalAccounts == nil || !*props.DisableLocalAccounts) {
accessProfileId := managedclusters.NewAccessProfileID(id.SubscriptionId, id.ResourceGroupName, id.ManagedClusterName, "clusterAdmin")
adminProfile, err := client.GetAccessProfile(ctx, accessProfileId)
adminCredentials, err := client.ListClusterAdminCredentials(ctx, *id, managedclusters.ListClusterAdminCredentialsOperationOptions{})
if err != nil {
return fmt.Errorf("retrieving Admin Access Profile for Managed Kubernetes Cluster %q (Resource Group %q): %+v", id.ManagedClusterName, id.ResourceGroupName, err)
return fmt.Errorf("retrieving Admin Credentials for %s: %+v", id, err)
}

if adminProfile.Model == nil {
return fmt.Errorf("retrieving Admin Access Profile for Managed Kubernetes Cluster %q (Resource Group %q): no payload found", id.ManagedClusterName, id.ResourceGroupName)
if adminCredentials.Model == nil {
return fmt.Errorf("retrieving Admin Credentials for Managed Kubernetes Cluster %q (Resource Group %q): no payload found", id.ManagedClusterName, id.ResourceGroupName)
}
adminKubeConfigRaw, adminKubeConfig := flattenKubernetesClusterAccessProfile(*adminProfile.Model)
adminKubeConfigRaw, adminKubeConfig := flattenKubernetesClusterCredentials(*adminCredentials.Model, "clusterAdmin")
d.Set("kube_admin_config_raw", adminKubeConfigRaw)
if err := d.Set("kube_admin_config", adminKubeConfig); err != nil {
return fmt.Errorf("setting `kube_admin_config`: %+v", err)
Expand All @@ -2394,7 +2393,7 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{})
return fmt.Errorf("setting `identity`: %+v", err)
}

kubeConfigRaw, kubeConfig := flattenKubernetesClusterAccessProfile(*profile.Model)
kubeConfigRaw, kubeConfig := flattenKubernetesClusterCredentials(*credentials.Model, "clusterUser")
d.Set("kube_config_raw", kubeConfigRaw)
if err := d.Set("kube_config", kubeConfig); err != nil {
return fmt.Errorf("setting `kube_config`: %+v", err)
Expand Down Expand Up @@ -2443,37 +2442,6 @@ func resourceKubernetesClusterDelete(d *pluginsdk.ResourceData, meta interface{}
return nil
}

func flattenKubernetesClusterAccessProfile(profile managedclusters.ManagedClusterAccessProfile) (*string, []interface{}) {
if accessProfile := profile.Properties; accessProfile != nil {
if kubeConfigRaw := accessProfile.KubeConfig; kubeConfigRaw != nil {
rawConfig := *kubeConfigRaw
if base64IsEncoded(*kubeConfigRaw) {
rawConfig = base64Decode(*kubeConfigRaw)
}
var flattenedKubeConfig []interface{}

if strings.Contains(rawConfig, "apiserver-id:") || strings.Contains(rawConfig, "exec") {
kubeConfigAAD, err := kubernetes.ParseKubeConfigAAD(rawConfig)
if err != nil {
return utils.String(rawConfig), []interface{}{}
}

flattenedKubeConfig = flattenKubernetesClusterKubeConfigAAD(*kubeConfigAAD)
} else {
kubeConfig, err := kubernetes.ParseKubeConfig(rawConfig)
if err != nil {
return utils.String(rawConfig), []interface{}{}
}

flattenedKubeConfig = flattenKubernetesClusterKubeConfig(*kubeConfig)
}

return utils.String(rawConfig), flattenedKubeConfig
}
}
return nil, []interface{}{}
}

func expandKubernetesClusterLinuxProfile(input []interface{}) *managedclusters.ContainerServiceLinuxProfile {
if len(input) == 0 {
return nil
Expand Down Expand Up @@ -3333,41 +3301,6 @@ func flattenAzureRmKubernetesClusterServicePrincipalProfile(profile *managedclus
}
}

func flattenKubernetesClusterKubeConfig(config kubernetes.KubeConfig) []interface{} {
// we don't size-check these since they're validated in the Parse method
cluster := config.Clusters[0].Cluster
user := config.Users[0].User
name := config.Users[0].Name

return []interface{}{
map[string]interface{}{
"client_certificate": user.ClientCertificteData,
"client_key": user.ClientKeyData,
"cluster_ca_certificate": cluster.ClusterAuthorityData,
"host": cluster.Server,
"password": user.Token,
"username": name,
},
}
}

func flattenKubernetesClusterKubeConfigAAD(config kubernetes.KubeConfigAAD) []interface{} {
// we don't size-check these since they're validated in the Parse method
cluster := config.Clusters[0].Cluster
name := config.Users[0].Name

return []interface{}{
map[string]interface{}{
"client_certificate": "",
"client_key": "",
"cluster_ca_certificate": cluster.ClusterAuthorityData,
"host": cluster.Server,
"password": "",
"username": name,
},
}
}

func flattenKubernetesClusterAutoScalerProfile(profile *managedclusters.ManagedClusterPropertiesAutoScalerProfile) ([]interface{}, error) {
if profile == nil {
return []interface{}{}, nil
Expand Down

0 comments on commit bd2e923

Please sign in to comment.