From 85f3eaa4918441e63350fb3c87f09da865cfae08 Mon Sep 17 00:00:00 2001 From: hellertang Date: Wed, 18 Oct 2023 16:44:55 +0800 Subject: [PATCH 1/3] add tke oidc --- .../data_source_tc_cam_oidc_config.go | 157 ++++++++++++++++++ .../data_source_tc_cam_oidc_config_test.go | 38 +++++ tencentcloud/provider.go | 2 + .../resource_tc_kubernetes_auth_attachment.go | 101 ++++++++++- tencentcloud/service_tencentcloud_tke.go | 7 +- website/docs/d/cam_oidc_config.html.markdown | 48 ++++++ .../kubernetes_auth_attachment.html.markdown | 30 ++++ website/tencentcloud.erb | 3 + 8 files changed, 381 insertions(+), 5 deletions(-) create mode 100644 tencentcloud/data_source_tc_cam_oidc_config.go create mode 100644 tencentcloud/data_source_tc_cam_oidc_config_test.go create mode 100644 website/docs/d/cam_oidc_config.html.markdown diff --git a/tencentcloud/data_source_tc_cam_oidc_config.go b/tencentcloud/data_source_tc_cam_oidc_config.go new file mode 100644 index 0000000000..7cae3177a1 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_oidc_config.go @@ -0,0 +1,157 @@ +/* +Use this data source to query detailed information of cam oidc_config + +Example Usage + +```hcl +data "tencentcloud_cam_oidc_config" "oidc_config" { + name = "cls-kzilgv5m" +} + +output "identity_key" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_key +} + +output "identity_url" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_url +} + +``` +*/ +package tencentcloud + +import ( + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func dataSourceTencentCloudCamOidcConfig() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamOidcConfigRead, + Schema: map[string]*schema.Schema{ + "name": { + Required: true, + Type: schema.TypeString, + Description: "Name.", + }, + + "provider_type": { + Computed: true, + Type: schema.TypeInt, + Description: "IdP type. 11: Role IdP.", + }, + + "identity_url": { + Computed: true, + Type: schema.TypeString, + Description: "IdP URL.", + }, + + "identity_key": { + Computed: true, + Type: schema.TypeString, + Description: "Public key for signature.", + }, + + "client_id": { + Computed: true, + Type: schema.TypeSet, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Client ID.", + }, + + "status": { + Computed: true, + Type: schema.TypeInt, + Description: "Status. 0: Not set; 2: Disabled; 11: Enabled.", + }, + + "description": { + Computed: true, + Type: schema.TypeString, + Description: "Description.", + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + }, + } +} + +func dataSourceTencentCloudCamOidcConfigRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_oidc_config.read")() + defer inconsistentCheck(d, meta)() + + logId := getLogId(contextNil) + var name string + result := make(map[string]interface{}) + + request := cam.NewDescribeOIDCConfigRequest() + + if v, ok := d.GetOk("name"); ok { + name = v.(string) + request.Name = helper.String(v.(string)) + } + + var response *cam.DescribeOIDCConfigResponse + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DescribeOIDCConfig(request) + if e != nil { + return retryError(e) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM role SSO failed, reason:%s\n", logId, err.Error()) + return err + } + + if response.Response.ProviderType != nil { + _ = d.Set("provider_type", response.Response.ProviderType) + result["provider_type"] = response.Response.ProviderType + } + + if response.Response.IdentityUrl != nil { + _ = d.Set("identity_url", response.Response.IdentityUrl) + result["identity_url"] = response.Response.IdentityUrl + } + + if response.Response.IdentityKey != nil { + _ = d.Set("identity_key", response.Response.IdentityKey) + result["identity_key"] = response.Response.IdentityKey + } + + if response.Response.ClientId != nil { + _ = d.Set("client_id", response.Response.ClientId) + result["client_id"] = response.Response.ClientId + } + + if response.Response.Status != nil { + _ = d.Set("status", response.Response.Status) + result["status"] = response.Response.Status + } + + if response.Response.Description != nil { + _ = d.Set("description", response.Response.Description) + result["description"] = response.Response.Description + } + + d.SetId(name) + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), result); e != nil { + return e + } + } + return nil +} diff --git a/tencentcloud/data_source_tc_cam_oidc_config_test.go b/tencentcloud/data_source_tc_cam_oidc_config_test.go new file mode 100644 index 0000000000..ea356eb90e --- /dev/null +++ b/tencentcloud/data_source_tc_cam_oidc_config_test.go @@ -0,0 +1,38 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccTencentCloudCamOidcConfigDataSource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCamOidcConfigDataSource, + Check: resource.ComposeTestCheckFunc(testAccCheckTencentCloudDataSourceID("data.tencentcloud_cam_oidc_config.oidc_config")), + }, + }, + }) +} + +const testAccCamOidcConfigDataSource = ` + +data "tencentcloud_cam_oidc_config" "oidc_config" { + name = "cls-kzilgv5m" +} + +output "identity_key" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_key +} + +output "identity_url" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_url +} +` diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 121a1f9028..f9645c91e8 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -227,6 +227,7 @@ Cloud Access Management(CAM) tencentcloud_cam_secret_last_used_time tencentcloud_cam_account_summary tencentcloud_cam_policy_granting_service_access + tencentcloud_cam_oidc_config Resource tencentcloud_cam_role @@ -2194,6 +2195,7 @@ func Provider() *schema.Provider { "tencentcloud_cam_saml_providers": dataSourceTencentCloudCamSAMLProviders(), "tencentcloud_cam_list_entities_for_policy": dataSourceTencentCloudCamListEntitiesForPolicy(), "tencentcloud_cam_account_summary": dataSourceTencentCloudCamAccountSummary(), + "tencentcloud_cam_oidc_config": dataSourceTencentCloudCamOidcConfig(), "tencentcloud_user_info": datasourceTencentCloudUserInfo(), "tencentcloud_cdn_domains": dataSourceTencentCloudCdnDomains(), "tencentcloud_cdn_domain_verifier": dataSourceTencentCloudCdnDomainVerifyRecord(), diff --git a/tencentcloud/resource_tc_kubernetes_auth_attachment.go b/tencentcloud/resource_tc_kubernetes_auth_attachment.go index 45e0251585..e1aa76955e 100644 --- a/tencentcloud/resource_tc_kubernetes_auth_attachment.go +++ b/tencentcloud/resource_tc_kubernetes_auth_attachment.go @@ -136,6 +136,34 @@ resource "tencentcloud_kubernetes_auth_attachment" "test_use_tke_default_auth_at use_tke_default = true } ``` + +Use OIDC Config +``` +resource "tencentcloud_kubernetes_auth_attachment" "test_auth_attach" { + cluster_id = tencentcloud_kubernetes_cluster.managed_cluster.id + use_tke_default = true + auto_create_discovery_anonymous_auth = true + auto_create_oidc_config = true + auto_install_pod_identity_webhook_addon = true +} + +data "tencentcloud_cam_oidc_config" "oidc_config" { + name = tencentcloud_kubernetes_cluster.managed_cluster.id + depends_on = [ + tencentcloud_kubernetes_auth_attachment.test_auth_attach + ] +} + +output "identity_key" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_key +} + +output "identity_url" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_url +} + +``` + */ package tencentcloud @@ -178,6 +206,27 @@ func resourceTencentCloudTKEAuthAttachment() *schema.Resource { Default: false, Description: "If set to `true`, the rbac rule will be created automatically which allow anonymous user to access '/.well-known/openid-configuration' and '/openid/v1/jwks'.", }, + "auto_create_oidc_config": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Creating an identity provider.", + }, + "auto_create_client_id": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Creating ClientId of the identity provider.", + }, + "auto_install_pod_identity_webhook_addon": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Creating the PodIdentityWebhook component.", + }, "tke_default_issuer": { Type: schema.TypeString, Computed: true, @@ -221,6 +270,20 @@ func resourceTencentCloudTKEAuthAttachmentCreate(d *schema.ResourceData, meta in request.ServiceAccounts.JWKSURI = helper.String(v.(string)) } } + request.OIDCConfig = &tke.OIDCConfigAuthenticationOptions{} + if v, ok := d.GetOkExists("auto_create_oidc_config"); ok { + request.OIDCConfig.AutoCreateOIDCConfig = helper.Bool(v.(bool)) + } + if v, ok := d.GetOkExists("auto_create_client_id"); ok { + clientsSet := v.(*schema.Set).List() + for i := range clientsSet { + client := clientsSet[i].(string) + request.OIDCConfig.AutoCreateClientId = append(request.OIDCConfig.AutoCreateClientId, &client) + } + } + if v, ok := d.GetOkExists("auto_install_pod_identity_webhook_addon"); ok { + request.OIDCConfig.AutoInstallPodIdentityWebhookAddon = helper.Bool(v.(bool)) + } err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { err := service.ModifyClusterAuthenticationOptions(ctx, request) @@ -245,7 +308,7 @@ func resourceTencentCloudTKEAuthAttachmentRead(d *schema.ResourceData, meta inte id := d.Id() service := TkeService{client: meta.(*TencentCloudClient).apiV3Conn} - info, err := service.WaitForAuthenticationOptionsUpdateSuccess(ctx, id) + info, oidc, err := service.WaitForAuthenticationOptionsUpdateSuccess(ctx, id) if err != nil { d.SetId("") @@ -262,6 +325,17 @@ func resourceTencentCloudTKEAuthAttachmentRead(d *schema.ResourceData, meta inte _ = d.Set("issuer", info.Issuer) } + if oidc.AutoCreateOIDCConfig != nil { + _ = d.Set("auto_create_oidc_config", oidc.AutoCreateOIDCConfig) + } + + if oidc.AutoCreateClientId != nil { + _ = d.Set("auto_create_client_id", oidc.AutoCreateClientId) + } + + if oidc.AutoInstallPodIdentityWebhookAddon != nil { + _ = d.Set("auto_install_pod_identity_webhook_addon", oidc.AutoInstallPodIdentityWebhookAddon) + } return nil } @@ -299,6 +373,29 @@ func resourceTencentCloudTKEAuthAttachmentUpdate(d *schema.ResourceData, meta in } } + request.OIDCConfig = &tke.OIDCConfigAuthenticationOptions{} + if d.HasChange("auto_create_oidc_config") { + if v, ok := d.GetOkExists("auto_create_oidc_config"); ok { + request.OIDCConfig.AutoCreateOIDCConfig = helper.Bool(v.(bool)) + } + } + + if d.HasChange("auto_create_client_id") { + if v, ok := d.GetOkExists("auto_create_client_id"); ok { + clientsSet := v.(*schema.Set).List() + for i := range clientsSet { + client := clientsSet[i].(string) + request.OIDCConfig.AutoCreateClientId = append(request.OIDCConfig.AutoCreateClientId, &client) + } + } + } + + if d.HasChange("auto_install_pod_identity_webhook_addon") { + if v, ok := d.GetOkExists("auto_install_pod_identity_webhook_addon"); ok { + request.OIDCConfig.AutoInstallPodIdentityWebhookAddon = helper.Bool(v.(bool)) + } + } + err := resource.Retry(3*writeRetryTimeout, func() *resource.RetryError { err := service.ModifyClusterAuthenticationOptions(ctx, request) if err != nil { @@ -333,7 +430,7 @@ func resourceTencentCloudTKEAuthAttachmentDelete(d *schema.ResourceData, meta in return err } - _, err := service.WaitForAuthenticationOptionsUpdateSuccess(ctx, id) + _, _, err := service.WaitForAuthenticationOptionsUpdateSuccess(ctx, id) if err != nil { return err diff --git a/tencentcloud/service_tencentcloud_tke.go b/tencentcloud/service_tencentcloud_tke.go index 80f9479cc1..6d875168ca 100644 --- a/tencentcloud/service_tencentcloud_tke.go +++ b/tencentcloud/service_tencentcloud_tke.go @@ -1502,10 +1502,11 @@ func (me *TkeService) DescribeClusterNodePoolGlobalConfig(ctx context.Context, c return } -func (me *TkeService) WaitForAuthenticationOptionsUpdateSuccess(ctx context.Context, id string) (info *tke.ServiceAccountAuthenticationOptions, errRet error) { - err := resource.Retry(readRetryTimeout, func() *resource.RetryError { - options, state, _, err := me.DescribeClusterAuthenticationOptions(ctx, id) +func (me *TkeService) WaitForAuthenticationOptionsUpdateSuccess(ctx context.Context, id string) (info *tke.ServiceAccountAuthenticationOptions, oidc *tke.OIDCConfigAuthenticationOptions, errRet error) { + err := resource.Retry(2*readRetryTimeout, func() *resource.RetryError { + options, state, config, err := me.DescribeClusterAuthenticationOptions(ctx, id) info = options + oidc = config if err != nil { return resource.NonRetryableError(err) diff --git a/website/docs/d/cam_oidc_config.html.markdown b/website/docs/d/cam_oidc_config.html.markdown new file mode 100644 index 0000000000..81cbf06b3c --- /dev/null +++ b/website/docs/d/cam_oidc_config.html.markdown @@ -0,0 +1,48 @@ +--- +subcategory: "Cloud Access Management(CAM)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_oidc_config" +sidebar_current: "docs-tencentcloud-datasource-cam_oidc_config" +description: |- + Use this data source to query detailed information of cam oidc_config +--- + +# tencentcloud_cam_oidc_config + +Use this data source to query detailed information of cam oidc_config + +## Example Usage + +```hcl +data "tencentcloud_cam_oidc_config" "oidc_config" { + name = "cls-kzilgv5m" +} + +output "identity_key" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_key +} + +output "identity_url" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_url +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required, String) Name. +* `result_output_file` - (Optional, String) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `client_id` - Client ID. +* `description` - Description. +* `identity_key` - Public key for signature. +* `identity_url` - IdP URL. +* `provider_type` - IdP type. 11: Role IdP. +* `status` - Status. 0: Not set; 2: Disabled; 11: Enabled. + + diff --git a/website/docs/r/kubernetes_auth_attachment.html.markdown b/website/docs/r/kubernetes_auth_attachment.html.markdown index 34bf068ca7..9378d0b01c 100644 --- a/website/docs/r/kubernetes_auth_attachment.html.markdown +++ b/website/docs/r/kubernetes_auth_attachment.html.markdown @@ -147,12 +147,42 @@ resource "tencentcloud_kubernetes_auth_attachment" "test_use_tke_default_auth_at } ``` +### Use OIDC Config + +```hcl +resource "tencentcloud_kubernetes_auth_attachment" "test_auth_attach" { + cluster_id = tencentcloud_kubernetes_cluster.managed_cluster.id + use_tke_default = true + auto_create_discovery_anonymous_auth = true + auto_create_oidc_config = true + auto_install_pod_identity_webhook_addon = true +} + +data "tencentcloud_cam_oidc_config" "oidc_config" { + name = tencentcloud_kubernetes_cluster.managed_cluster.id + depends_on = [ + tencentcloud_kubernetes_auth_attachment.test_auth_attach + ] +} + +output "identity_key" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_key +} + +output "identity_url" { + value = data.tencentcloud_cam_oidc_config.oidc_config.identity_url +} +``` + ## Argument Reference The following arguments are supported: * `cluster_id` - (Required, String) ID of clusters. +* `auto_create_client_id` - (Optional, Set: [`String`]) Creating ClientId of the identity provider. * `auto_create_discovery_anonymous_auth` - (Optional, Bool) If set to `true`, the rbac rule will be created automatically which allow anonymous user to access '/.well-known/openid-configuration' and '/openid/v1/jwks'. +* `auto_create_oidc_config` - (Optional, Bool) Creating an identity provider. +* `auto_install_pod_identity_webhook_addon` - (Optional, Bool) Creating the PodIdentityWebhook component. * `issuer` - (Optional, String) Specify service-account-issuer. If use_tke_default is set to `true`, please do not set this field. * `jwks_uri` - (Optional, String) Specify service-account-jwks-uri. If use_tke_default is set to `true`, please do not set this field. * `use_tke_default` - (Optional, Bool) If set to `true`, the issuer and jwks_uri will be generated automatically by tke, please do not set issuer and jwks_uri. diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index cb63e78229..4930727d44 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -497,6 +497,9 @@
  • tencentcloud_cam_list_entities_for_policy
  • +
  • + tencentcloud_cam_oidc_config +
  • tencentcloud_cam_policies
  • From 4306d4cdbe4835b7e709d520ab18e539e98a0532 Mon Sep 17 00:00:00 2001 From: hellertang Date: Wed, 18 Oct 2023 16:47:32 +0800 Subject: [PATCH 2/3] add changelog --- .changelog/2227.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/2227.txt diff --git a/.changelog/2227.txt b/.changelog/2227.txt new file mode 100644 index 0000000000..15bd03f0fd --- /dev/null +++ b/.changelog/2227.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/tencentcloud_kubernetes_auth_attachment: Support OIDC config. +``` + +```release-note:new-data-source +tencentcloud_cam_oidc_config +``` \ No newline at end of file From e14aa058d42a3e4345c19ae02ca63d8d31645edf Mon Sep 17 00:00:00 2001 From: hellertang Date: Wed, 18 Oct 2023 19:54:16 +0800 Subject: [PATCH 3/3] update --- .../resource_tc_kubernetes_auth_attachment.go | 27 ++++++++++--------- .../kubernetes_auth_attachment.html.markdown | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/tencentcloud/resource_tc_kubernetes_auth_attachment.go b/tencentcloud/resource_tc_kubernetes_auth_attachment.go index e1aa76955e..87f0434285 100644 --- a/tencentcloud/resource_tc_kubernetes_auth_attachment.go +++ b/tencentcloud/resource_tc_kubernetes_auth_attachment.go @@ -185,20 +185,23 @@ func resourceTencentCloudTKEAuthAttachment() *schema.Resource { Required: true, Description: "ID of clusters.", }, - "issuer": { - Type: schema.TypeString, - Optional: true, - Description: "Specify service-account-issuer. If use_tke_default is set to `true`, please do not set this field.", - }, "use_tke_default": { - Type: schema.TypeBool, - Optional: true, - Description: "If set to `true`, the issuer and jwks_uri will be generated automatically by tke, please do not set issuer and jwks_uri.", + Type: schema.TypeBool, + Optional: true, + ConflictsWith: []string{"issuer", "jwks_uri"}, + Description: "If set to `true`, the issuer and jwks_uri will be generated automatically by tke, please do not set issuer and jwks_uri.", + }, + "issuer": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"use_tke_default"}, + Description: "Specify service-account-issuer. If use_tke_default is set to `true`, please do not set this field.", }, "jwks_uri": { - Type: schema.TypeString, - Optional: true, - Description: "Specify service-account-jwks-uri. If use_tke_default is set to `true`, please do not set this field.", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"use_tke_default"}, + Description: "Specify service-account-jwks-uri. If use_tke_default is set to `true`, please do not set this field.", }, "auto_create_discovery_anonymous_auth": { Type: schema.TypeBool, @@ -225,7 +228,7 @@ func resourceTencentCloudTKEAuthAttachment() *schema.Resource { Type: schema.TypeBool, Optional: true, Computed: true, - Description: "Creating the PodIdentityWebhook component.", + Description: "Creating the PodIdentityWebhook component. if `auto_create_oidc_config` is true, this field must set true.", }, "tke_default_issuer": { Type: schema.TypeString, diff --git a/website/docs/r/kubernetes_auth_attachment.html.markdown b/website/docs/r/kubernetes_auth_attachment.html.markdown index 9378d0b01c..f9c73f4ef4 100644 --- a/website/docs/r/kubernetes_auth_attachment.html.markdown +++ b/website/docs/r/kubernetes_auth_attachment.html.markdown @@ -182,7 +182,7 @@ The following arguments are supported: * `auto_create_client_id` - (Optional, Set: [`String`]) Creating ClientId of the identity provider. * `auto_create_discovery_anonymous_auth` - (Optional, Bool) If set to `true`, the rbac rule will be created automatically which allow anonymous user to access '/.well-known/openid-configuration' and '/openid/v1/jwks'. * `auto_create_oidc_config` - (Optional, Bool) Creating an identity provider. -* `auto_install_pod_identity_webhook_addon` - (Optional, Bool) Creating the PodIdentityWebhook component. +* `auto_install_pod_identity_webhook_addon` - (Optional, Bool) Creating the PodIdentityWebhook component. if `auto_create_oidc_config` is true, this field must set true. * `issuer` - (Optional, String) Specify service-account-issuer. If use_tke_default is set to `true`, please do not set this field. * `jwks_uri` - (Optional, String) Specify service-account-jwks-uri. If use_tke_default is set to `true`, please do not set this field. * `use_tke_default` - (Optional, Bool) If set to `true`, the issuer and jwks_uri will be generated automatically by tke, please do not set issuer and jwks_uri.