From 6d94b9787a1460917032c3e39588a36bf3b04267 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Fri, 31 Mar 2023 12:56:08 +0200 Subject: [PATCH 1/2] `azurerm_kubernetes_cluster`: ensuring that `kube_admin_config` and `kube_admin_config_raw` always get a value --- .../kubernetes_cluster_data_source.go | 41 +- .../containers/kubernetes_cluster_resource.go | 423 +++++++++--------- 2 files changed, 226 insertions(+), 238 deletions(-) diff --git a/internal/services/containers/kubernetes_cluster_data_source.go b/internal/services/containers/kubernetes_cluster_data_source.go index 83b5a28b9540..59fc92d45326 100644 --- a/internal/services/containers/kubernetes_cluster_data_source.go +++ b/internal/services/containers/kubernetes_cluster_data_source.go @@ -9,11 +9,11 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" "github.com/hashicorp/go-azure-helpers/resourcemanager/zones" "github.com/hashicorp/go-azure-sdk/resource-manager/containerservice/2023-01-02-preview/managedclusters" "github.com/hashicorp/go-azure-sdk/resource-manager/operationalinsights/2020-08-01/workspaces" - "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/services/containers/kubernetes" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" @@ -692,22 +692,16 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{} return fmt.Errorf("retrieving %s: %+v", id, err) } - credentials, err := client.ListClusterUserCredentials(ctx, id, managedclusters.ListClusterUserCredentialsOperationOptions{}) + userCredentialsResp, err := client.ListClusterUserCredentials(ctx, id, managedclusters.ListClusterUserCredentialsOperationOptions{}) if err != nil { - return fmt.Errorf("retrieving User Credentials 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) - } - credentialsModel := credentials.Model d.SetId(id.ID()) if model := resp.Model; model != nil { - d.Set("name", model.Name) + d.Set("name", id.ManagedClusterName) d.Set("resource_group_name", id.ResourceGroupName) - if location := model.Location; location != "" { - d.Set("location", azure.NormalizeLocation(location)) - } + d.Set("location", location.Normalize(model.Location)) if props := model.Properties; props != nil { d.Set("dns_prefix", props.DnsPrefix) @@ -824,22 +818,19 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{} } // adminProfile is only available for RBAC enabled clusters with AAD and without local accounts disabled + adminKubeConfig := make([]interface{}, 0) + var adminKubeConfigRaw *string if props.AadProfile != nil && (props.DisableLocalAccounts == nil || !*props.DisableLocalAccounts) { - adminCredentials, err := client.ListClusterAdminCredentials(ctx, id, managedclusters.ListClusterAdminCredentialsOperationOptions{}) + adminCredentialsResp, err := client.ListClusterAdminCredentials(ctx, id, managedclusters.ListClusterAdminCredentialsOperationOptions{}) if err != nil { return fmt.Errorf("retrieving Admin Credentials for %s: %+v", id, err) } - 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) - } - } - } else { - d.Set("kube_admin_config_raw", "") - d.Set("kube_admin_config", []interface{}{}) + adminKubeConfigRaw, adminKubeConfig = flattenKubernetesClusterCredentials(adminCredentialsResp.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) } } @@ -852,7 +843,7 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{} return fmt.Errorf("setting `identity`: %+v", err) } - kubeConfigRaw, kubeConfig := flattenKubernetesClusterCredentials(*credentialsModel, "clusterUser") + kubeConfigRaw, kubeConfig := flattenKubernetesClusterCredentials(userCredentialsResp.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) @@ -928,8 +919,8 @@ func flattenKubernetesClusterDataSourceStorageProfile(input *managedclusters.Man return storageProfile } -func flattenKubernetesClusterCredentials(model managedclusters.CredentialResults, configName string) (*string, []interface{}) { - if model.Kubeconfigs == nil || len(*model.Kubeconfigs) < 1 { +func flattenKubernetesClusterCredentials(model *managedclusters.CredentialResults, configName string) (*string, []interface{}) { + if model == nil || model.Kubeconfigs == nil || len(*model.Kubeconfigs) < 1 { return nil, []interface{}{} } diff --git a/internal/services/containers/kubernetes_cluster_resource.go b/internal/services/containers/kubernetes_cluster_resource.go index 6e510b443e18..a5584c16e1a0 100644 --- a/internal/services/containers/kubernetes_cluster_resource.go +++ b/internal/services/containers/kubernetes_cluster_resource.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/edgezones" "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" + "github.com/hashicorp/go-azure-helpers/resourcemanager/location" "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" "github.com/hashicorp/go-azure-sdk/resource-manager/containerservice/2023-01-02-preview/agentpools" "github.com/hashicorp/go-azure-sdk/resource-manager/containerservice/2023-01-02-preview/maintenanceconfigurations" @@ -2139,11 +2140,6 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}) return fmt.Errorf("retrieving %s: %+v", *id, err) } - respModel := resp.Model - if respModel == nil { - return fmt.Errorf("retrieving %s: no payload delivered", *id) - } - credentials, err := client.ListClusterUserCredentials(ctx, *id, managedclusters.ListClusterUserCredentialsOperationOptions{}) if err != nil { return fmt.Errorf("retrieving User Credentials for %s: %+v", id, err) @@ -2154,259 +2150,260 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}) d.Set("name", id.ManagedClusterName) d.Set("resource_group_name", id.ResourceGroupName) - d.Set("edge_zone", flattenEdgeZone(respModel.ExtendedLocation)) - if location := respModel.Location; location != "" { - d.Set("location", azure.NormalizeLocation(location)) - } - - skuTier := string(managedclusters.ManagedClusterSKUTierFree) - if respModel.Sku != nil && respModel.Sku.Tier != nil && *respModel.Sku.Tier != "" { - skuTier = string(*respModel.Sku.Tier) - } - d.Set("sku_tier", skuTier) - - if props := respModel.Properties; props != nil { - d.Set("dns_prefix", props.DnsPrefix) - d.Set("dns_prefix_private_cluster", props.FqdnSubdomain) - d.Set("fqdn", props.Fqdn) - d.Set("private_fqdn", props.PrivateFQDN) - d.Set("portal_fqdn", props.AzurePortalFQDN) - d.Set("disk_encryption_set_id", props.DiskEncryptionSetID) - d.Set("kubernetes_version", props.KubernetesVersion) - d.Set("enable_pod_security_policy", props.EnablePodSecurityPolicy) - d.Set("local_account_disabled", props.DisableLocalAccounts) - nodeResourceGroup := "" - if v := props.NodeResourceGroup; v != nil { - nodeResourceGroup = *props.NodeResourceGroup - } - d.Set("node_resource_group", nodeResourceGroup) + if model := resp.Model; model != nil { + d.Set("edge_zone", flattenEdgeZone(model.ExtendedLocation)) + d.Set("location", location.Normalize(model.Location)) + + skuTier := string(managedclusters.ManagedClusterSKUTierFree) + if model.Sku != nil && model.Sku.Tier != nil && *model.Sku.Tier != "" { + skuTier = string(*model.Sku.Tier) + } + d.Set("sku_tier", skuTier) + + if props := model.Properties; props != nil { + d.Set("dns_prefix", props.DnsPrefix) + d.Set("dns_prefix_private_cluster", props.FqdnSubdomain) + d.Set("fqdn", props.Fqdn) + d.Set("private_fqdn", props.PrivateFQDN) + d.Set("portal_fqdn", props.AzurePortalFQDN) + d.Set("disk_encryption_set_id", props.DiskEncryptionSetID) + d.Set("kubernetes_version", props.KubernetesVersion) + d.Set("enable_pod_security_policy", props.EnablePodSecurityPolicy) + d.Set("local_account_disabled", props.DisableLocalAccounts) + + nodeResourceGroup := "" + if v := props.NodeResourceGroup; v != nil { + nodeResourceGroup = *props.NodeResourceGroup + } + d.Set("node_resource_group", nodeResourceGroup) - nodeResourceGroupId := commonids.NewResourceGroupID(id.SubscriptionId, nodeResourceGroup) - d.Set("node_resource_group_id", nodeResourceGroupId.ID()) + nodeResourceGroupId := commonids.NewResourceGroupID(id.SubscriptionId, nodeResourceGroup) + d.Set("node_resource_group_id", nodeResourceGroupId.ID()) - publicNetworkAccess := managedclusters.PublicNetworkAccessEnabled - if props.PublicNetworkAccess != nil { - publicNetworkAccess = *props.PublicNetworkAccess - } - d.Set("public_network_access_enabled", publicNetworkAccess != managedclusters.PublicNetworkAccessDisabled) + publicNetworkAccess := managedclusters.PublicNetworkAccessEnabled + if props.PublicNetworkAccess != nil { + publicNetworkAccess = *props.PublicNetworkAccess + } + d.Set("public_network_access_enabled", publicNetworkAccess != managedclusters.PublicNetworkAccessDisabled) - upgradeChannel := "" - if profile := props.AutoUpgradeProfile; profile != nil && profile.UpgradeChannel != nil && *profile.UpgradeChannel != managedclusters.UpgradeChannelNone { - upgradeChannel = string(*profile.UpgradeChannel) - } - d.Set("automatic_channel_upgrade", upgradeChannel) + upgradeChannel := "" + if profile := props.AutoUpgradeProfile; profile != nil && profile.UpgradeChannel != nil && *profile.UpgradeChannel != managedclusters.UpgradeChannelNone { + upgradeChannel = string(*profile.UpgradeChannel) + } + d.Set("automatic_channel_upgrade", upgradeChannel) - enablePrivateCluster := false - enablePrivateClusterPublicFQDN := false - runCommandEnabled := true + enablePrivateCluster := false + enablePrivateClusterPublicFQDN := false + runCommandEnabled := true - apiServerAccessProfile := flattenKubernetesClusterAPIAccessProfile(props.ApiServerAccessProfile) - if err := d.Set("api_server_access_profile", apiServerAccessProfile); err != nil { - return fmt.Errorf("setting `api_server_access_profile`: %+v", err) - } - if accessProfile := props.ApiServerAccessProfile; accessProfile != nil { - if !features.FourPointOhBeta() { - apiServerAuthorizedIPRanges := utils.FlattenStringSlice(accessProfile.AuthorizedIPRanges) - if err := d.Set("api_server_authorized_ip_ranges", apiServerAuthorizedIPRanges); err != nil { - return fmt.Errorf("setting `api_server_authorized_ip_ranges`: %+v", err) + apiServerAccessProfile := flattenKubernetesClusterAPIAccessProfile(props.ApiServerAccessProfile) + if err := d.Set("api_server_access_profile", apiServerAccessProfile); err != nil { + return fmt.Errorf("setting `api_server_access_profile`: %+v", err) + } + if accessProfile := props.ApiServerAccessProfile; accessProfile != nil { + if !features.FourPointOhBeta() { + apiServerAuthorizedIPRanges := utils.FlattenStringSlice(accessProfile.AuthorizedIPRanges) + if err := d.Set("api_server_authorized_ip_ranges", apiServerAuthorizedIPRanges); err != nil { + return fmt.Errorf("setting `api_server_authorized_ip_ranges`: %+v", err) + } + } + if accessProfile.EnablePrivateCluster != nil { + enablePrivateCluster = *accessProfile.EnablePrivateCluster + } + if accessProfile.EnablePrivateClusterPublicFQDN != nil { + enablePrivateClusterPublicFQDN = *accessProfile.EnablePrivateClusterPublicFQDN + } + if accessProfile.DisableRunCommand != nil { + runCommandEnabled = !*accessProfile.DisableRunCommand + } + switch { + case accessProfile.PrivateDNSZone != nil && strings.EqualFold("System", *accessProfile.PrivateDNSZone): + d.Set("private_dns_zone_id", "System") + case accessProfile.PrivateDNSZone != nil && strings.EqualFold("None", *accessProfile.PrivateDNSZone): + d.Set("private_dns_zone_id", "None") + default: + d.Set("private_dns_zone_id", accessProfile.PrivateDNSZone) } } - if accessProfile.EnablePrivateCluster != nil { - enablePrivateCluster = *accessProfile.EnablePrivateCluster - } - if accessProfile.EnablePrivateClusterPublicFQDN != nil { - enablePrivateClusterPublicFQDN = *accessProfile.EnablePrivateClusterPublicFQDN - } - if accessProfile.DisableRunCommand != nil { - runCommandEnabled = !*accessProfile.DisableRunCommand - } - switch { - case accessProfile.PrivateDNSZone != nil && strings.EqualFold("System", *accessProfile.PrivateDNSZone): - d.Set("private_dns_zone_id", "System") - case accessProfile.PrivateDNSZone != nil && strings.EqualFold("None", *accessProfile.PrivateDNSZone): - d.Set("private_dns_zone_id", "None") - default: - d.Set("private_dns_zone_id", accessProfile.PrivateDNSZone) - } - } - d.Set("private_cluster_enabled", enablePrivateCluster) - d.Set("private_cluster_public_fqdn_enabled", enablePrivateClusterPublicFQDN) - d.Set("run_command_enabled", runCommandEnabled) - - if props.AddonProfiles != nil { - addOns := flattenKubernetesAddOns(*props.AddonProfiles) - d.Set("aci_connector_linux", addOns["aci_connector_linux"]) - d.Set("azure_policy_enabled", addOns["azure_policy_enabled"].(bool)) - d.Set("confidential_computing", addOns["confidential_computing"]) - d.Set("http_application_routing_enabled", addOns["http_application_routing_enabled"].(bool)) - d.Set("http_application_routing_zone_name", addOns["http_application_routing_zone_name"]) - d.Set("oms_agent", addOns["oms_agent"]) - d.Set("ingress_application_gateway", addOns["ingress_application_gateway"]) - d.Set("open_service_mesh_enabled", addOns["open_service_mesh_enabled"].(bool)) - d.Set("key_vault_secrets_provider", addOns["key_vault_secrets_provider"]) - } - autoScalerProfile, err := flattenKubernetesClusterAutoScalerProfile(props.AutoScalerProfile) - if err != nil { - return err - } - if err := d.Set("auto_scaler_profile", autoScalerProfile); err != nil { - return fmt.Errorf("setting `auto_scaler_profile`: %+v", err) - } - - azureMonitorProfile := flattenKubernetesClusterAzureMonitorProfile(props.AzureMonitorProfile) - if err := d.Set("monitor_metrics", azureMonitorProfile); err != nil { - return fmt.Errorf("setting `monitor_metrics`: %+v", err) - } - - flattenedDefaultNodePool, err := FlattenDefaultNodePool(props.AgentPoolProfiles, d) - if err != nil { - return fmt.Errorf("flattening `default_node_pool`: %+v", err) - } - if err := d.Set("default_node_pool", flattenedDefaultNodePool); err != nil { - return fmt.Errorf("setting `default_node_pool`: %+v", err) - } - - kubeletIdentity := []interface{}{} - if identityProfile := props.IdentityProfile; identityProfile != nil { - kubeletIdentity, err = flattenKubernetesClusterIdentityProfile(*props.IdentityProfile) + d.Set("private_cluster_enabled", enablePrivateCluster) + d.Set("private_cluster_public_fqdn_enabled", enablePrivateClusterPublicFQDN) + d.Set("run_command_enabled", runCommandEnabled) + + if props.AddonProfiles != nil { + addOns := flattenKubernetesAddOns(*props.AddonProfiles) + d.Set("aci_connector_linux", addOns["aci_connector_linux"]) + d.Set("azure_policy_enabled", addOns["azure_policy_enabled"].(bool)) + d.Set("confidential_computing", addOns["confidential_computing"]) + d.Set("http_application_routing_enabled", addOns["http_application_routing_enabled"].(bool)) + d.Set("http_application_routing_zone_name", addOns["http_application_routing_zone_name"]) + d.Set("oms_agent", addOns["oms_agent"]) + d.Set("ingress_application_gateway", addOns["ingress_application_gateway"]) + d.Set("open_service_mesh_enabled", addOns["open_service_mesh_enabled"].(bool)) + d.Set("key_vault_secrets_provider", addOns["key_vault_secrets_provider"]) + } + autoScalerProfile, err := flattenKubernetesClusterAutoScalerProfile(props.AutoScalerProfile) if err != nil { return err } - } + if err := d.Set("auto_scaler_profile", autoScalerProfile); err != nil { + return fmt.Errorf("setting `auto_scaler_profile`: %+v", err) + } - if err := d.Set("kubelet_identity", kubeletIdentity); err != nil { - return fmt.Errorf("setting `kubelet_identity`: %+v", err) - } + azureMonitorProfile := flattenKubernetesClusterAzureMonitorProfile(props.AzureMonitorProfile) + if err := d.Set("monitor_metrics", azureMonitorProfile); err != nil { + return fmt.Errorf("setting `monitor_metrics`: %+v", err) + } - linuxProfile := flattenKubernetesClusterLinuxProfile(props.LinuxProfile) - if err := d.Set("linux_profile", linuxProfile); err != nil { - return fmt.Errorf("setting `linux_profile`: %+v", err) - } + flattenedDefaultNodePool, err := FlattenDefaultNodePool(props.AgentPoolProfiles, d) + if err != nil { + return fmt.Errorf("flattening `default_node_pool`: %+v", err) + } + if err := d.Set("default_node_pool", flattenedDefaultNodePool); err != nil { + return fmt.Errorf("setting `default_node_pool`: %+v", err) + } - networkProfile := flattenKubernetesClusterNetworkProfile(props.NetworkProfile) - if err := d.Set("network_profile", networkProfile); err != nil { - return fmt.Errorf("setting `network_profile`: %+v", err) - } + kubeletIdentity := []interface{}{} + if identityProfile := props.IdentityProfile; identityProfile != nil { + kubeletIdentity, err = flattenKubernetesClusterIdentityProfile(*props.IdentityProfile) + if err != nil { + return err + } + } - rbacEnabled := true - if props.EnableRBAC != nil { - rbacEnabled = *props.EnableRBAC - } - d.Set("role_based_access_control_enabled", rbacEnabled) + if err := d.Set("kubelet_identity", kubeletIdentity); err != nil { + return fmt.Errorf("setting `kubelet_identity`: %+v", err) + } - aadRbac := flattenKubernetesClusterAzureActiveDirectoryRoleBasedAccessControl(props, d) - if err := d.Set("azure_active_directory_role_based_access_control", aadRbac); err != nil { - return fmt.Errorf("setting `azure_active_directory_role_based_access_control`: %+v", err) - } + linuxProfile := flattenKubernetesClusterLinuxProfile(props.LinuxProfile) + if err := d.Set("linux_profile", linuxProfile); err != nil { + return fmt.Errorf("setting `linux_profile`: %+v", err) + } - servicePrincipal := flattenAzureRmKubernetesClusterServicePrincipalProfile(props.ServicePrincipalProfile, d) - if err := d.Set("service_principal", servicePrincipal); err != nil { - return fmt.Errorf("setting `service_principal`: %+v", err) - } + networkProfile := flattenKubernetesClusterNetworkProfile(props.NetworkProfile) + if err := d.Set("network_profile", networkProfile); err != nil { + return fmt.Errorf("setting `network_profile`: %+v", err) + } - windowsProfile := flattenKubernetesClusterWindowsProfile(props.WindowsProfile, d) - if err := d.Set("windows_profile", windowsProfile); err != nil { - return fmt.Errorf("setting `windows_profile`: %+v", err) - } + rbacEnabled := true + if props.EnableRBAC != nil { + rbacEnabled = *props.EnableRBAC + } + d.Set("role_based_access_control_enabled", rbacEnabled) - workloadAutoscalerProfile := flattenKubernetesClusterWorkloadAutoscalerProfile(props.WorkloadAutoScalerProfile) - if err := d.Set("workload_autoscaler_profile", workloadAutoscalerProfile); err != nil { - return fmt.Errorf("setting `workload_autoscaler_profile`: %+v", err) - } + aadRbac := flattenKubernetesClusterAzureActiveDirectoryRoleBasedAccessControl(props, d) + if err := d.Set("azure_active_directory_role_based_access_control", aadRbac); err != nil { + return fmt.Errorf("setting `azure_active_directory_role_based_access_control`: %+v", err) + } - if props.SecurityProfile != nil && props.SecurityProfile.ImageCleaner != nil { - if props.SecurityProfile.ImageCleaner.Enabled != nil { - d.Set("image_cleaner_enabled", props.SecurityProfile.ImageCleaner.Enabled) + servicePrincipal := flattenAzureRmKubernetesClusterServicePrincipalProfile(props.ServicePrincipalProfile, d) + if err := d.Set("service_principal", servicePrincipal); err != nil { + return fmt.Errorf("setting `service_principal`: %+v", err) } - if props.SecurityProfile.ImageCleaner.IntervalHours != nil { - d.Set("image_cleaner_interval_hours", props.SecurityProfile.ImageCleaner.IntervalHours) + + windowsProfile := flattenKubernetesClusterWindowsProfile(props.WindowsProfile, d) + if err := d.Set("windows_profile", windowsProfile); err != nil { + return fmt.Errorf("setting `windows_profile`: %+v", err) } - } - httpProxyConfig := flattenKubernetesClusterHttpProxyConfig(props) - if err := d.Set("http_proxy_config", httpProxyConfig); err != nil { - return fmt.Errorf("setting `http_proxy_config`: %+v", err) - } + workloadAutoscalerProfile := flattenKubernetesClusterWorkloadAutoscalerProfile(props.WorkloadAutoScalerProfile) + if err := d.Set("workload_autoscaler_profile", workloadAutoscalerProfile); err != nil { + return fmt.Errorf("setting `workload_autoscaler_profile`: %+v", err) + } - oidcIssuerEnabled := false - oidcIssuerUrl := "" - if props.OidcIssuerProfile != nil { - if props.OidcIssuerProfile.Enabled != nil { - oidcIssuerEnabled = *props.OidcIssuerProfile.Enabled + if props.SecurityProfile != nil && props.SecurityProfile.ImageCleaner != nil { + if props.SecurityProfile.ImageCleaner.Enabled != nil { + d.Set("image_cleaner_enabled", props.SecurityProfile.ImageCleaner.Enabled) + } + if props.SecurityProfile.ImageCleaner.IntervalHours != nil { + d.Set("image_cleaner_interval_hours", props.SecurityProfile.ImageCleaner.IntervalHours) + } } - if props.OidcIssuerProfile.IssuerURL != nil { - oidcIssuerUrl = *props.OidcIssuerProfile.IssuerURL + + httpProxyConfig := flattenKubernetesClusterHttpProxyConfig(props) + if err := d.Set("http_proxy_config", httpProxyConfig); err != nil { + return fmt.Errorf("setting `http_proxy_config`: %+v", err) } - } - d.Set("oidc_issuer_enabled", oidcIssuerEnabled) - d.Set("oidc_issuer_url", oidcIssuerUrl) + oidcIssuerEnabled := false + oidcIssuerUrl := "" + if props.OidcIssuerProfile != nil { + if props.OidcIssuerProfile.Enabled != nil { + oidcIssuerEnabled = *props.OidcIssuerProfile.Enabled + } + if props.OidcIssuerProfile.IssuerURL != nil { + oidcIssuerUrl = *props.OidcIssuerProfile.IssuerURL + } + } - microsoftDefender := flattenKubernetesClusterMicrosoftDefender(props.SecurityProfile) - if err := d.Set("microsoft_defender", microsoftDefender); err != nil { - return fmt.Errorf("setting `microsoft_defender`: %+v", err) - } + d.Set("oidc_issuer_enabled", oidcIssuerEnabled) + d.Set("oidc_issuer_url", oidcIssuerUrl) - ingressProfile := flattenKubernetesClusterIngressProfile(props.IngressProfile) - if err := d.Set("web_app_routing", ingressProfile); err != nil { - return fmt.Errorf("setting `web_app_routing`: %+v", err) - } + microsoftDefender := flattenKubernetesClusterMicrosoftDefender(props.SecurityProfile) + if err := d.Set("microsoft_defender", microsoftDefender); err != nil { + return fmt.Errorf("setting `microsoft_defender`: %+v", err) + } - workloadIdentity := false - if props.SecurityProfile != nil && props.SecurityProfile.WorkloadIdentity != nil { - workloadIdentity = *props.SecurityProfile.WorkloadIdentity.Enabled - } - d.Set("workload_identity_enabled", workloadIdentity) + ingressProfile := flattenKubernetesClusterIngressProfile(props.IngressProfile) + if err := d.Set("web_app_routing", ingressProfile); err != nil { + return fmt.Errorf("setting `web_app_routing`: %+v", err) + } - azureKeyVaultKms := flattenKubernetesClusterDataSourceKeyVaultKms(props.SecurityProfile) - if err := d.Set("key_management_service", azureKeyVaultKms); err != nil { - return fmt.Errorf("setting `key_management_service`: %+v", err) - } + workloadIdentity := false + if props.SecurityProfile != nil && props.SecurityProfile.WorkloadIdentity != nil { + workloadIdentity = *props.SecurityProfile.WorkloadIdentity.Enabled + } + d.Set("workload_identity_enabled", workloadIdentity) - // 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) { - adminCredentials, err := client.ListClusterAdminCredentials(ctx, *id, managedclusters.ListClusterAdminCredentialsOperationOptions{}) - if err != nil { - return fmt.Errorf("retrieving Admin Credentials for %s: %+v", id, err) + azureKeyVaultKms := flattenKubernetesClusterDataSourceKeyVaultKms(props.SecurityProfile) + if err := d.Set("key_management_service", azureKeyVaultKms); err != nil { + return fmt.Errorf("setting `key_management_service`: %+v", err) } - 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) + + // adminProfile is only available for RBAC enabled clusters with AAD and local account is not disabled + var adminKubeConfigRaw *string + adminKubeConfig := make([]interface{}, 0) + if props.AadProfile != nil && (props.DisableLocalAccounts == nil || !*props.DisableLocalAccounts) { + adminCredentials, err := client.ListClusterAdminCredentials(ctx, *id, managedclusters.ListClusterAdminCredentialsOperationOptions{}) + if err != nil { + return fmt.Errorf("retrieving Admin Credentials for %s: %+v", id, err) + } + adminKubeConfigRaw, adminKubeConfig = flattenKubernetesClusterCredentials(adminCredentials.Model, "clusterAdmin") } - 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) } - } else { - d.Set("kube_admin_config_raw", "") - d.Set("kube_admin_config", []interface{}{}) } - } - identity, err := identity.FlattenSystemOrUserAssignedMap(respModel.Identity) - if err != nil { - return fmt.Errorf("setting `identity`: %+v", err) - } + identity, err := identity.FlattenSystemOrUserAssignedMap(model.Identity) + if err != nil { + return fmt.Errorf("setting `identity`: %+v", err) + } + if err := d.Set("identity", identity); err != nil { + return fmt.Errorf("setting `identity`: %+v", err) + } - if err := d.Set("identity", identity); err != nil { - return fmt.Errorf("setting `identity`: %+v", err) - } + 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) + } - 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) - } + maintenanceConfigurationsClient := meta.(*clients.Client).Containers.MaintenanceConfigurationsClient + maintenanceId := maintenanceconfigurations.NewMaintenanceConfigurationID(id.SubscriptionId, id.ResourceGroupName, id.ManagedClusterName, "default") + configResp, _ := maintenanceConfigurationsClient.Get(ctx, maintenanceId) + if configurationBody := configResp.Model; configurationBody != nil && configurationBody.Properties != nil { + d.Set("maintenance_window", flattenKubernetesClusterMaintenanceConfiguration(configurationBody.Properties)) + } - maintenanceConfigurationsClient := meta.(*clients.Client).Containers.MaintenanceConfigurationsClient - maintenanceId := maintenanceconfigurations.NewMaintenanceConfigurationID(id.SubscriptionId, id.ResourceGroupName, id.ManagedClusterName, "default") - configResp, _ := maintenanceConfigurationsClient.Get(ctx, maintenanceId) - if configurationBody := configResp.Model; configurationBody != nil && configurationBody.Properties != nil { - d.Set("maintenance_window", flattenKubernetesClusterMaintenanceConfiguration(configurationBody.Properties)) + if err := tags.FlattenAndSet(d, model.Tags); err != nil { + return fmt.Errorf("setting `tags`: %+v", err) + } } - return tags.FlattenAndSet(d, respModel.Tags) + return nil } func resourceKubernetesClusterDelete(d *pluginsdk.ResourceData, meta interface{}) error { From 32183787341214ad90742ad21062e14b6e0fe77f Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Fri, 31 Mar 2023 12:56:46 +0200 Subject: [PATCH 2/2] d/kubernetes_cluster: support a graceful degredation of permissions for the cluster kubernetes credentials --- .../services/containers/kubernetes_cluster_data_source.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/services/containers/kubernetes_cluster_data_source.go b/internal/services/containers/kubernetes_cluster_data_source.go index 59fc92d45326..98c8340fe500 100644 --- a/internal/services/containers/kubernetes_cluster_data_source.go +++ b/internal/services/containers/kubernetes_cluster_data_source.go @@ -2,6 +2,7 @@ package containers import ( "fmt" + "net/http" "strings" "time" @@ -693,7 +694,8 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{} } userCredentialsResp, err := client.ListClusterUserCredentials(ctx, id, managedclusters.ListClusterUserCredentialsOperationOptions{}) - if err != nil { + // only raise the error if it's not a limited permissions error, since this is the Data Source + if err != nil && !response.WasStatusCode(userCredentialsResp.HttpResponse, http.StatusForbidden) { return fmt.Errorf("retrieving User Credentials for %s: %+v", id, err) } @@ -822,7 +824,8 @@ func dataSourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{} var adminKubeConfigRaw *string if props.AadProfile != nil && (props.DisableLocalAccounts == nil || !*props.DisableLocalAccounts) { adminCredentialsResp, err := client.ListClusterAdminCredentials(ctx, id, managedclusters.ListClusterAdminCredentialsOperationOptions{}) - if err != nil { + // only raise the error if it's not a limited permissions error, since this is the Data Source + if err != nil && !response.WasStatusCode(adminCredentialsResp.HttpResponse, http.StatusForbidden) { return fmt.Errorf("retrieving Admin Credentials for %s: %+v", id, err) }