diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1a7f238c..d1f5de7d51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,24 @@ FEATURES: +* **New Data Source**: `tencentcloud_cam_users` +* **New Data Source**: `tencentcloud_cam_groups` +* **New Data Source**: `tencentcloud_cam_policies` +* **New Data Source**: `tencentcloud_cam_roles` +* **New Data Source**: `tencentcloud_cam_user_policy_attachments` +* **New Data Source**: `tencentcloud_cam_group_policy_attachments` +* **New Data Source**: `tencentcloud_cam_role_policy_attachments` +* **New Data Source**: `tencentcloud_cam_group_memberships` +* **New Data Source**: `tencentcloud_cam_SAML_providers` +* **New Resource**: `tencentcloud_cam_user` +* **New Resource**: `tencentcloud_cam_group` +* **New Resource**: `tencentcloud_cam_role` +* **New Resource**: `tencentcloud_cam_policy` +* **New Resource**: `tencentcloud_cam_user_policy_attachment` +* **New Resource**: `tencentcloud_cam_group_policy_attachment` +* **New Resource**: `tencentcloud_cam_role_policy_attachment` +* **New Resource**: `tencentcloud_cam_group_membership` +* **New Resource**: `tencentcloud_cam_SAML_provider` * **New Data Source**: `tencentcloud_reserved_instance_configs` * **New Data Source**: `tencentcloud_reserved_instances` * **New Resource**: `tencentcloud_reserved_instance` @@ -15,6 +33,7 @@ BUG FIXES: * Resource: `tencentcloud_gaap_http_domain` fix sometimes can't enable realserver auth + ## 1.20.1 (October 08, 2019) ENHANCEMENTS: diff --git a/examples/tencentcloud-cam/main.tf b/examples/tencentcloud-cam/main.tf new file mode 100644 index 0000000000..86a5a7efb6 --- /dev/null +++ b/examples/tencentcloud-cam/main.tf @@ -0,0 +1,90 @@ +resource "tencentcloud_cam_group" "example" { + name = "example" + remark = "example" +} + +resource "tencentcloud_cam_user" "example" { + name = "example" + remark = "example" + console_login = true + use_api = true + need_reset_password = true + password = "${var.password}" + phone_num = "${var.phone_num}" + country_code = "${var.country_code}" + email = "${var.email}" +} + +resource "tencentcloud_cam_policy" "example" { + name = "example" + document = "${var.policy_document}" +} + +resource "tencentcloud_cam_role" "example" { + name = "example" + document = "${var.role_document}" + description = "test" + console_login = true +} + +resource "tencentcloud_cam_group_membership" "example" { + group_id = "${tencentcloud_cam_group.example.id}" + user_ids = ["${tencentcloud_cam_user.example.id}"] +} + +resource "tencentcloud_cam_role_policy_attachment" "example" { + role_id = "${tencentcloud_cam_role.example.id}" + policy_id = "${tencentcloud_cam_policy.example.id}" +} + +resource "tencentcloud_cam_user_policy_attachment" "example" { + user_id = "${tencentcloud_cam_user.example.id}" + policy_id = "${tencentcloud_cam_policy.example.id}" +} + +resource "tencentcloud_cam_group_policy_attachment" "example" { + group_id = "${tencentcloud_cam_group.example.id}" + policy_id = "${tencentcloud_cam_policy.example.id}" +} + +resource "tencentcloud_cam_saml_provider" "example" { + name = "example" + meta_data = "${var.meta_data}" + description = "test" +} + +data "tencentcloud_cam_users" "users" { + name = "${tencentcloud_cam_user.example.id}" +} + +data "tencentcloud_cam_roles" "roles" { + role_id = "${tencentcloud_cam_role.example.id}" +} + +data "tencentcloud_cam_policies" "policies" { + policy_id = "${tencentcloud_cam_policy.example.id}" +} + +data "tencentcloud_cam_groups" "groups" { + group_id = "${tencentcloud_cam_group.example.id}" +} + +data "tencentcloud_cam_group_memberships" "memberships" { + group_id = "${tencentcloud_cam_group_membership.example.id}" +} + +data "tencentcloud_cam_user_policy_attachments" "user_policy_attachments" { + user_id = "${tencentcloud_cam_user_policy_attachment.example.user_id}" +} + +data "tencentcloud_cam_role_policy_attachments" "role_policy_attachments" { + role_id = "${tencentcloud_cam_role_policy_attachment.example.role_id}" +} + +data "tencentcloud_cam_group_policy_attachments" "group_policy_attachments" { + group_id = "${tencentcloud_cam_group_policy_attachment.example.group_id}" +} + +data "tencentcloud_cam_saml_providers" "saml_providers" { + name = "${tencentcloud_cam_saml_provider.example.id}" +} \ No newline at end of file diff --git a/examples/tencentcloud-cam/variables.tf b/examples/tencentcloud-cam/variables.tf new file mode 100644 index 0000000000..606cdfcc25 --- /dev/null +++ b/examples/tencentcloud-cam/variables.tf @@ -0,0 +1,28 @@ +variable "password" { + default = "Gail@1234" +} + +variable "phone_num" { + default = "13631555963" +} + +variable "country_code" { + default = "86" +} + +variable "email" { + default = "1234@qq.com" +} + +variable "policy_document" { + default = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]},{\"action\":[\"name/cos:PutObject\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" +} + +variable "role_document" { + default = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}}]}" +} + +variable "meta_data" { + default = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48bWQ6RW50aXR5RGVzY3JpcHRvciBlbnRpdHlJRD0iaHR0cDovL3d3dy5va3RhLmNvbS9leGsxa3F4bWNqUW1HQURNeTM1NyIgeG1sbnM6bWQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSI+PG1kOklEUFNTT0Rlc2NyaXB0b3IgV2FudEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48bWQ6S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEb0RDQ0FvaWdBd0lCQWdJR0FXM0lTcExvTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdRTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHDQpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVDQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0dsa2VIVmxkblJoTVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwDQpibVp2UUc5cmRHRXVZMjl0TUI0WERURTVNVEF4TkRBek1qSXhNMW9YRFRJNU1UQXhOREF6TWpNeE0xb3dnWkF4Q3pBSkJnTlZCQVlUDQpBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFLDQpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJYVdSNGRXVjJkR0V4SERBYUJna3Foa2lHDQo5dzBCQ1FFV0RXbHVabTlBYjJ0MFlTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2g4b3dqDQpZK2dQSUM3blQvNTduLzdmeXJzcDlHMXdxa2UxdXhjMHVrTndnQXozOVNpelY3QVhLMWRReTFLaThXWjJJMzFEczJkT0FNQ1FKR2pWDQpUWWNNbnA3KzhqUzNLdmxNUkRJamk5cmxuUi9vcnBvMll1RHVWby9jVzdidlRIS2h2REo1QWZRaWxzYlNPTXdUOWM2TVlYZGhBNVBwDQpzelFsK1UrdHJmcXUrdUorSER4SVQxdlhWaVI5YlY2SUFRSzZpbWZoc2wxWmVSUytjbVFVNEpjQWlYT0xtTnFVVWM2UkpxUzhrMW1mDQpBLzhmb2VyMGc3SG4xZDVXclpCc2gyUlR2Vzh1ZVdadHQ3dmh4QTlGdE5kSVlEcXJ0eElmMlZXcXhrSHM3WFZDSm5wTnJITVovT1BRDQpGY21YSGVxNlJJMlB3Q1RlOW8zZHZpM0hqeXBaOEl4dkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFHaHk1bG9nbGtTDQoyVHg2YS90MnF5VEx0YVV5cEwrNGhySGJoMVAweVVMc0NrSnFsM2wrWG9VZDZCY2FJaFNSVGFPQk95ODViL0UzelJ4K3JzQXJwTjVVDQp5ZThuUEM4a05PYW5vTk9wWnZvYmhpTzFlMFIvYmxEcnRBL0o5UlBwMWtmdlhmS2NSTTU3TlRCWXppTURlbnFQUTRFOWN1U2lGdFFxDQpJYmpIbThaM1B1YXgwRitldkZ3U1pJMDNCWXNISGw1d1EraEJBS3hTdTJINEZRdU93Zmpnb2EveEN6Z1NKYjJ2UXdEc1MxMk9mSkNiDQpSRm1ZL1VYZXQramFhdEVORktLZStZSUJpU0J2WG1adTN0MHN5NDZTNzlPVzBacXJ0NUh2bElsT2lpTFpaN1FZamxjM1kxeG1LZ1luDQpXM2M2WGZkdmhGWHo0ZDdkbWYvTUdpNGY0enM9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9tZDpLZXlEZXNjcmlwdG9yPjxtZDpOYW1lSURGb3JtYXQ+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQ8L21kOk5hbWVJREZvcm1hdD48bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzczwvbWQ6TmFtZUlERm9ybWF0PjxtZDpTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkeHVldnRhLm9rdGEuY29tL2FwcC9pZHh1ZW9yZzYzNzM1OF90ZXN0XzEvZXhrMWtxeG1jalFtR0FETXkzNTcvc3NvL3NhbWwiLz48bWQ6U2luZ2xlU2lnbk9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWR4dWV2dGEub2t0YS5jb20vYXBwL2lkeHVlb3JnNjM3MzU4X3Rlc3RfMS9leGsxa3F4bWNqUW1HQURNeTM1Ny9zc28vc2FtbCIvPjwvbWQ6SURQU1NPRGVzY3JpcHRvcj48L21kOkVudGl0eURlc2NyaXB0b3I+" +} + diff --git a/tencentcloud/connectivity/client.go b/tencentcloud/connectivity/client.go index 06acdbd3f6..d780268780 100644 --- a/tencentcloud/connectivity/client.go +++ b/tencentcloud/connectivity/client.go @@ -10,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" as "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/as/v20180419" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" cbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312" cdb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb/v20170320" clb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317" @@ -43,6 +44,7 @@ type TencentCloudClient struct { tagConn *tag.Client mongodbConn *mongodb.Client tkeConn *tke.Client + camConn *cam.Client gaapCoon *gaap.Client sslCoon *ssl.Client } @@ -401,3 +403,27 @@ func (me *TencentCloudClient) UseSslClient() *ssl.Client { return me.sslCoon } + +func (me *TencentCloudClient) UseCamClient() *cam.Client { + if me.camConn != nil { + return me.camConn + } + + credential := common.NewCredential( + me.SecretId, + me.SecretKey, + ) + + cpf := profile.NewClientProfile() + cpf.HttpProfile.ReqMethod = "POST" + cpf.HttpProfile.ReqTimeout = 300 + cpf.Language = "en-US" + + camConn, _ := cam.NewClient(credential, me.Region, cpf) + var round LogRoundTripper + + camConn.WithHttpTransport(&round) + me.camConn = camConn + + return me.camConn +} diff --git a/tencentcloud/data_source_tc_cam_group_memberships.go b/tencentcloud/data_source_tc_cam_group_memberships.go new file mode 100644 index 0000000000..6a90d467a8 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_group_memberships.go @@ -0,0 +1,109 @@ +/* +Use this data source to query detailed information of CAM groups + +Example Usage + +```hcl +data "tencentcloud_cam_group_memberships" "foo" { + group_id = "12515263" +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceTencentCloudCamGroupMemberships() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamGroupMembershipsRead, + + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Optional: true, + Description: "Id of CAM group to be queried.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "membership_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM group membership. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Id of CAM group.", + }, + "user_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Id set of the CAM group members.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamGroupMembershipsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_group_memberships.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + groupId := d.Get("group_id").(string) + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var memberships []*string + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeGroupMembershipById(ctx, groupId) + if e != nil { + return retryError(e) + } + memberships = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM group memberships failed, reason:%s\n", logId, err.Error()) + return err + } + groupList := make([]map[string]interface{}, 0, 1) + ids := make([]string, 0, 1) + mapping := map[string]interface{}{ + "group_id": groupId, + "user_ids": memberships, + } + groupList = append(groupList, mapping) + ids = append(ids, groupId) + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("membership_list", groupList); e != nil { + log.Printf("[CRITAL]%s provider set membershiplist fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), groupList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_group_memberships_test.go b/tencentcloud/data_source_tc_cam_group_memberships_test.go new file mode 100644 index 0000000000..f27b4a8f01 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_group_memberships_test.go @@ -0,0 +1,54 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamGroupMembershipsDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamGroupMembershipDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamGroupMembershipsDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamGroupExists("tencentcloud_cam_group_membership.membership"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_group_memberships.memberships", "membership_list.#", "1"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_group_memberships.memberships", "membership_list.0.group_id"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_group_memberships.memberships", "membership_list.0.user_ids.#", "1"), + ), + }, + }, + }) +} + +const testAccCamGroupMembershipsDataSource_basic = ` +resource "tencentcloud_cam_group" "group_basic" { + name = "cam-group-membership-test" + remark = "test" +} + +resource "tencentcloud_cam_user" "user_basic" { + name = "cam-user-testj" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} + +resource "tencentcloud_cam_group_membership" "membership" { + group_id = "${tencentcloud_cam_group.group_basic.id}" + user_ids = ["${tencentcloud_cam_user.user_basic.id}"] +} + +data "tencentcloud_cam_group_memberships" "memberships" { + group_id = "${tencentcloud_cam_group_membership.membership.id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_group_policy_attachments.go b/tencentcloud/data_source_tc_cam_group_policy_attachments.go new file mode 100644 index 0000000000..75f3adf853 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_group_policy_attachments.go @@ -0,0 +1,166 @@ +/* +Use this data source to query detailed information of CAM group policy attachments + +Example Usage + +```hcl +data "tencentcloud_cam_group_policy_attachments" "foo" { + group_id = "12515263" + policy_id = "215153266" + policy_type = "QCS" + create_mode = 1 +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamGroupPolicyAttachments() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamGroupPolicyAttachmentsRead, + + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of the attached CAM group to be queried.", + }, + "policy_id": { + Type: schema.TypeString, + Optional: true, + Description: "Id of CAM policy to be queried.", + }, + "create_mode": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateAllowedIntValue([]int{1, 2}), + Description: "Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAllowedStringValue(CAM_POLICY_CREATE_STRATEGY), + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "group_policy_attachment_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM group policy attachments. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Computed: true, + Description: "Id of CAM group.", + }, + "policy_id": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM group.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of Creation of the CAM group policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the policy strategy. 'Group' means customer strategy and 'QCS' means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM group policy attachment.", + }, + "policy_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the policy.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamGroupPolicyAttachmentsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_group_policy_attachments.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + groupId := d.Get("group_id").(string) + params["group_id"] = groupId + if v, ok := d.GetOk("policy_id"); ok { + params["policy_id"] = uint64(v.(int)) + } + if v, ok := d.GetOk("policy_type"); ok { + params["policy_type"] = v.(string) + } + if v, ok := d.GetOk("create_mode"); ok { + params["create_mode"] = v.(int) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var policyOfGroups []*cam.AttachPolicyInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeGroupPolicyAttachmentsByFilter(ctx, params) + if e != nil { + return retryError(e) + } + policyOfGroups = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM group policy attachments failed, reason:%s\n", logId, err.Error()) + return err + } + policyOfGroupList := make([]map[string]interface{}, 0, len(policyOfGroups)) + ids := make([]string, 0, len(policyOfGroups)) + for _, policy := range policyOfGroups { + mapping := map[string]interface{}{ + "group_id": groupId, + "policy_id": strconv.Itoa(int(*policy.PolicyId)), + "create_time": *policy.AddTime, + "create_mode": *policy.CreateMode, + "policy_type": *policy.PolicyType, + "policy_name": *policy.PolicyName, + } + policyOfGroupList = append(policyOfGroupList, mapping) + ids = append(ids, groupId+"#"+strconv.Itoa(int(*policy.PolicyId))) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("group_policy_attachment_list", policyOfGroupList); e != nil { + log.Printf("[CRITAL]%s provider set group polilcy attachment list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), policyOfGroupList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_group_policy_attachments_test.go b/tencentcloud/data_source_tc_cam_group_policy_attachments_test.go new file mode 100644 index 0000000000..4e5113d7df --- /dev/null +++ b/tencentcloud/data_source_tc_cam_group_policy_attachments_test.go @@ -0,0 +1,50 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamGroupPolicyAttachmentsDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamGroupPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamGroupPolicyAttachmentsDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamGroupPolicyAttachmentExists("tencentcloud_cam_group_policy_attachment.group_policy_attachment"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_group_policy_attachments.group_policy_attachments", "group_policy_attachment_list.#", "1"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_group_policy_attachments.group_policy_attachments", "group_policy_attachment_list.0.group_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_group_policy_attachments.group_policy_attachments", "group_policy_attachment_list.0.policy_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_group_policy_attachments.group_policy_attachments", "group_policy_attachment_list.0.policy_name"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_group_policy_attachments.group_policy_attachments", "group_policy_attachment_list.0.create_mode"), + ), + }, + }, + }) +} + +const testAccCamGroupPolicyAttachmentsDataSource_basic = ` +resource "tencentcloud_cam_group" "group" { + name = "cam-group-policy-test" + remark = "test" +} + +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test8" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +resource "tencentcloud_cam_group_policy_attachment" "group_policy_attachment" { + group_id = "${tencentcloud_cam_group.group.id}" + policy_id = "${tencentcloud_cam_policy.policy.id}" +} + +data "tencentcloud_cam_group_policy_attachments" "group_policy_attachments" { + group_id = "${tencentcloud_cam_group_policy_attachment.group_policy_attachment.group_id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_groups.go b/tencentcloud/data_source_tc_cam_groups.go new file mode 100644 index 0000000000..dcff6ba1b1 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_groups.go @@ -0,0 +1,138 @@ +/* +Use this data source to query detailed information of CAM groups + +Example Usage + +```hcl +data "tencentcloud_cam_groups" "foo" { + group_id = "12515263" + name = "cam-role-test" + remark = "test" +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamGroups() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamGroupsRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the CAM group to be queried.", + }, + "group_id": { + Type: schema.TypeString, + Optional: true, + Description: "Id of CAM group to be queried.", + }, + "remark": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the cam group.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "group_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM groups. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM group.", + }, + "remark": { + Type: schema.TypeString, + Computed: true, + Description: "Description of CAM group.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM group.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamGroupsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_groups.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + if v, ok := d.GetOk("group_id"); ok { + params["group_id"], _ = strconv.Atoi(v.(string)) + } + if v, ok := d.GetOk("name"); ok { + params["name"] = v.(string) + } + if v, ok := d.GetOk("remark"); ok { + params["remark"] = v.(string) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var groups []*cam.GroupInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeGroupsByFilter(ctx, params) + if e != nil { + return retryError(e) + } + groups = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM groups failed, reason:%s\n", logId, err.Error()) + return err + } + groupList := make([]map[string]interface{}, 0, len(groups)) + ids := make([]string, 0, len(groups)) + for _, group := range groups { + mapping := map[string]interface{}{ + "name": *group.GroupName, + "remark": *group.Remark, + "create_time": *group.CreateTime, + } + groupList = append(groupList, mapping) + ids = append(ids, strconv.Itoa(int(*group.GroupId))) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("group_list", groupList); e != nil { + log.Printf("[CRITAL]%s provider set group list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), groupList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_groups_test.go b/tencentcloud/data_source_tc_cam_groups_test.go new file mode 100644 index 0000000000..1d03538b7c --- /dev/null +++ b/tencentcloud/data_source_tc_cam_groups_test.go @@ -0,0 +1,38 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamGroupsDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamGroupsDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamGroupExists("tencentcloud_cam_group.group"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_groups.groups", "group_list.#", "1"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_groups.groups", "group_list.0.name", "cam-group-test3"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_groups.groups", "group_list.0.remark", "test"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_groups.groups", "group_list.0.create_time"), + ), + }, + }, + }) +} + +const testAccCamGroupsDataSource_basic = ` +resource "tencentcloud_cam_group" "group" { + name = "cam-group-test3" + remark = "test" +} + +data "tencentcloud_cam_groups" "groups" { + group_id = "${tencentcloud_cam_group.group.id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_policies.go b/tencentcloud/data_source_tc_cam_policies.go new file mode 100644 index 0000000000..eb5ac6d723 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_policies.go @@ -0,0 +1,182 @@ +/* +Use this data source to query detailed information of CAM policies + +Example Usage + +```hcl +data "tencentcloud_cam_policies" "foo" { + policy_id = "26655801" + name = "cam-policy-test" + type = 1 + create_mode = 1 + description = "test" +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamPolicies() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamPoliciesRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the CAM policy to be queried.", + }, + "policy_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of CAM policy to be queried to be queried.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "The description of the CAM policy .", + }, + "type": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateAllowedIntValue([]int{1, 2}), + Description: "Type of the policy strategy. 1 means customer strategy and 2 means preset strategy.", + }, + "create_mode": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateAllowedIntValue([]int{1, 2}), + Description: "Mode of creation of policy strategy. 1 means policy was created with console, and 2 means it was created by strategies.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "policy_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM policies. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM policy.", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of CAM policy.", + }, + "attachments": { + Type: schema.TypeInt, + Computed: true, + Description: "Number of attached users.", + }, + "service_type": { + Type: schema.TypeString, + Computed: true, + Description: "Name of attached products.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM policy.", + }, + "type": { + Type: schema.TypeInt, + Computed: true, + Description: "Type of the policy strategy. 1 means customer strategy and 2 means preset strategy.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of creation of policy strategy. 1 means policy was created with console, and 2 means it was created by strategies.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamPoliciesRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_policies.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + if v, ok := d.GetOk("policy_id"); ok { + params["policy_id"], _ = strconv.Atoi(v.(string)) + } + if v, ok := d.GetOk("name"); ok { + params["name"] = v.(string) + } + if v, ok := d.GetOk("description"); ok { + params["description"] = v.(string) + } + if v, ok := d.GetOk("create_mode"); ok { + params["create_mode"] = v.(int) + } + if v, ok := d.GetOk("type"); ok { + params["type"] = v.(int) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var policies []*cam.StrategyInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribePoliciesByFilter(ctx, params) + if e != nil { + return retryError(e) + } + policies = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM policies failed, reason:%s\n", logId, err.Error()) + return err + } + policyList := make([]map[string]interface{}, 0, len(policies)) + ids := make([]string, 0, len(policies)) + for _, policy := range policies { + mapping := map[string]interface{}{ + "name": *policy.PolicyName, + "attachments": int(*policy.Attachments), + "description": *policy.Description, + "create_time": *policy.AddTime, + "service_type": *policy.ServiceType, + "create_mode": int(*policy.CreateMode), + "type": int(*policy.Type), + } + policyList = append(policyList, mapping) + ids = append(ids, strconv.Itoa(int(*policy.PolicyId))) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("policy_list", policyList); e != nil { + log.Printf("[CRITAL]%s provider set policy list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), policyList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_policies_test.go b/tencentcloud/data_source_tc_cam_policies_test.go new file mode 100644 index 0000000000..7b4ea9f2a9 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_policies_test.go @@ -0,0 +1,42 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamPoliciesDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamPoliciesDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamPolicyExists("tencentcloud_cam_policy.policy"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_policies.policies", "policy_list.#", "1"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_policies.policies", "policy_list.0.name", "cam-policy-test5"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_policies.policies", "policy_list.0.description", "test"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_policies.policies", "policy_list.0.attachments"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_policies.policies", "policy_list.0.create_time"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_policies.policies", "policy_list.0.service_type"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_policies.policies", "policy_list.0.create_mode"), + ), + }, + }, + }) +} + +const testAccCamPoliciesDataSource_basic = ` +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test5" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +data "tencentcloud_cam_policies" "policies" { + policy_id = "${tencentcloud_cam_policy.policy.id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_role_policy_attachments.go b/tencentcloud/data_source_tc_cam_role_policy_attachments.go new file mode 100644 index 0000000000..37e2d07c7b --- /dev/null +++ b/tencentcloud/data_source_tc_cam_role_policy_attachments.go @@ -0,0 +1,166 @@ +/* +Use this data source to query detailed information of CAM role policy attachments + +Example Usage + +```hcl +data "tencentcloud_cam_role_policy_attachments" "foo" { + role_id = "4611686018427922725" + policy_id = "26800353" + policy_type = "QCS" + create_mode = 1 +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamRolePolicyAttachments() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamRolePolicyAttachmentsRead, + + Schema: map[string]*schema.Schema{ + "role_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of the attached CAM role to be queried.", + }, + "policy_id": { + Type: schema.TypeString, + Optional: true, + Description: "Id of CAM policy to be queried.", + }, + "create_mode": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateAllowedIntValue([]int{1, 2}), + Description: "Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAllowedStringValue(CAM_POLICY_CREATE_STRATEGY), + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "role_policy_attachment_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM role policy attachments. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "role_id": { + Type: schema.TypeString, + Computed: true, + Description: "Id of CAM role.", + }, + "policy_id": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM role.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of Creation of the CAM role policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM role policy attachment.", + }, + "policy_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the policy.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamRolePolicyAttachmentsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_role_policy_attachments.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + roleId := d.Get("role_id").(string) + params["role_id"] = roleId + if v, ok := d.GetOk("policy_id"); ok { + params["policy_id"] = uint64(v.(int)) + } + if v, ok := d.GetOk("policy_type"); ok { + params["policy_type"] = v.(string) + } + if v, ok := d.GetOk("create_mode"); ok { + params["create_mode"] = v.(int) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var policyOfRoles []*cam.AttachedPolicyOfRole + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeRolePolicyAttachmentsByFilter(ctx, params) + if e != nil { + return retryError(e) + } + policyOfRoles = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM role policy attachments failed, reason:%s\n", logId, err.Error()) + return err + } + policyOfRoleList := make([]map[string]interface{}, 0, len(policyOfRoles)) + ids := make([]string, 0, len(policyOfRoles)) + for _, policy := range policyOfRoles { + mapping := map[string]interface{}{ + "role_id": roleId, + "policy_id": strconv.Itoa(int(*policy.PolicyId)), + "create_time": *policy.AddTime, + "create_mode": *policy.CreateMode, + "policy_type": *policy.PolicyType, + "policy_name": *policy.PolicyName, + } + policyOfRoleList = append(policyOfRoleList, mapping) + ids = append(ids, roleId+"#"+strconv.Itoa(int(*policy.PolicyId))) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("role_policy_attachment_list", policyOfRoleList); e != nil { + log.Printf("[CRITAL]%s provider set role polilcy attachment list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), policyOfRoleList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_role_policy_attachments_test.go b/tencentcloud/data_source_tc_cam_role_policy_attachments_test.go new file mode 100644 index 0000000000..d28c154b80 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_role_policy_attachments_test.go @@ -0,0 +1,52 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamRolePolicyAttachmentsDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamRolePolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamRolePolicyAttachmentsDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamRolePolicyAttachmentExists("tencentcloud_cam_role_policy_attachment.role_policy_attachment"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_role_policy_attachments.role_policy_attachments", "role_policy_attachment_list.#", "1"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_role_policy_attachments.role_policy_attachments", "role_policy_attachment_list.0.role_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_role_policy_attachments.role_policy_attachments", "role_policy_attachment_list.0.policy_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_role_policy_attachments.role_policy_attachments", "role_policy_attachment_list.0.policy_name"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_role_policy_attachments.role_policy_attachments", "role_policy_attachment_list.0.create_mode"), + ), + }, + }, + }) +} + +const testAccCamRolePolicyAttachmentsDataSource_basic = ` +resource "tencentcloud_cam_role" "role" { + name = "cam-role-test" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}}]}" + description = "test" + console_login = true +} + +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test6" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +resource "tencentcloud_cam_role_policy_attachment" "role_policy_attachment" { + role_id = "${tencentcloud_cam_role.role.id}" + policy_id = "${tencentcloud_cam_policy.policy.id}" +} + +data "tencentcloud_cam_role_policy_attachments" "role_policy_attachments" { + role_id = "${tencentcloud_cam_role_policy_attachment.role_policy_attachment.role_id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_roles.go b/tencentcloud/data_source_tc_cam_roles.go new file mode 100644 index 0000000000..3505d5dec9 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_roles.go @@ -0,0 +1,165 @@ +/* +Use this data source to query detailed information of CAM roles + +Example Usage + +```hcl +data "tencentcloud_cam_roles" "foo" { + role_id = "14151513226" + name = "cam-role-test" + description = "test" +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamRoles() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamRolesRead, + + Schema: map[string]*schema.Schema{ + "role_id": { + Type: schema.TypeString, + Optional: true, + Description: "Id of the CAM role to be queried.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "The description of the CAM role to be queried.", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the CAM policy to be queried.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "role_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM roles. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "role_id": { + Type: schema.TypeString, + Computed: true, + Description: "Id of CAM role.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM role.", + }, + "document": { + Type: schema.TypeString, + Computed: true, + Description: "Policy document of CAM role.", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of CAM role.", + }, + "console_login": { + Type: schema.TypeBool, + Computed: true, + Description: "Indicate whether the CAM role can be login or not.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "The create time of the CAM role.", + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "The last update time of the CAM role.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamRolesRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_roles.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + if v, ok := d.GetOk("role_id"); ok { + params["role_id"] = v.(string) + } + if v, ok := d.GetOk("name"); ok { + params["name"] = v.(string) + } + if v, ok := d.GetOk("description"); ok { + params["description"] = v.(string) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var roles []*cam.RoleInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeRolesByFilter(ctx, params) + if e != nil { + return retryError(e) + } + roles = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM roles failed, reason:%s\n", logId, err.Error()) + return err + } + roleList := make([]map[string]interface{}, 0, len(roles)) + ids := make([]string, 0, len(roles)) + for _, role := range roles { + mapping := map[string]interface{}{ + "role_id": *role.RoleId, + "name": *role.RoleName, + "document": *role.PolicyDocument, + "description": *role.Description, + "create_time": *role.AddTime, + "update_time": *role.UpdateTime, + } + if int(*role.ConsoleLogin) == 1 { + mapping["console_login"] = true + } else { + mapping["console_login"] = false + } + roleList = append(roleList, mapping) + ids = append(ids, *role.RoleId) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("role_list", roleList); e != nil { + log.Printf("[CRITAL]%s provider set CAM role list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), roleList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_roles_test.go b/tencentcloud/data_source_tc_cam_roles_test.go new file mode 100644 index 0000000000..1959bc66cd --- /dev/null +++ b/tencentcloud/data_source_tc_cam_roles_test.go @@ -0,0 +1,44 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamRolesDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamRoleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamRolesDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamRoleExists("tencentcloud_cam_role.role"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_roles.roles", "role_list.#", "1"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_roles.roles", "role_list.0.role_id"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_roles.roles", "role_list.0.name", "cam-role-test11"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_roles.roles", "role_list.0.description", "test"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_roles.roles", "role_list.0.console_login", "true"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_roles.roles", "role_list.0.create_time"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_roles.roles", "role_list.0.update_time"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_roles.roles", "role_list.0.document"), + ), + }, + }, + }) +} + +const testAccCamRolesDataSource_basic = ` +resource "tencentcloud_cam_role" "role" { + name = "cam-role-test11" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}}]}" + description = "test" + console_login = true +} + +data "tencentcloud_cam_roles" "roles" { + role_id = "${tencentcloud_cam_role.role.id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_saml_providers.go b/tencentcloud/data_source_tc_cam_saml_providers.go new file mode 100644 index 0000000000..0946a7cfd3 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_saml_providers.go @@ -0,0 +1,133 @@ +/* +Use this data source to query detailed information of CAM SAML providers + +Example Usage + +```hcl +data "tencentcloud_cam_saml_providers" "foo" { + name = "cam-test-provider" +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamSAMLProviders() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamSAMLProvidersRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of the CAM SAML provider to be queried.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "The description of the CAM SAML provider .", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "provider_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM SAML providers. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM SAML provider.", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "Description of CAM SAML provider.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM SAML provider.", + }, + "modify_time": { + Type: schema.TypeString, + Computed: true, + Description: "The last modify time of the CAM SAML provider.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamSAMLProvidersRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_SAML_providers.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + if v, ok := d.GetOk("name"); ok { + params["name"] = v.(string) + } + if v, ok := d.GetOk("description"); ok { + params["description"] = v.(string) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var providers []*cam.SAMLProviderInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeSAMLProvidersByFilter(ctx, params) + if e != nil { + return retryError(e) + } + providers = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM groups failed, reason:%s\n", logId, err.Error()) + return err + } + providerList := make([]map[string]interface{}, 0, len(providers)) + ids := make([]string, 0, len(providers)) + for _, provider := range providers { + mapping := map[string]interface{}{ + "name": *provider.Name, + "description": *provider.Description, + "create_time": *provider.CreateTime, + "modify_time": *provider.ModifyTime, + } + providerList = append(providerList, mapping) + ids = append(ids, *provider.Name) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("provider_list", providerList); e != nil { + log.Printf("[CRITAL]%s provider set provider list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), providerList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_saml_providers_test.go b/tencentcloud/data_source_tc_cam_saml_providers_test.go new file mode 100644 index 0000000000..c2b44e435f --- /dev/null +++ b/tencentcloud/data_source_tc_cam_saml_providers_test.go @@ -0,0 +1,40 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamSAMLProvidersDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamSAMLProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamSAMLProvidersDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamSAMLProviderExists("tencentcloud_cam_saml_provider.provider"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_saml_providers.saml_providers", "provider_list.#", "1"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_saml_providers.saml_providers", "provider_list.0.name", "cam-provider-test1"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_saml_providers.saml_providers", "provider_list.0.description", "test"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_saml_providers.saml_providers", "provider_list.0.create_time"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_saml_providers.saml_providers", "provider_list.0.modify_time"), + ), + }, + }, + }) +} + +const testAccCamSAMLProvidersDataSource_basic = ` +resource "tencentcloud_cam_saml_provider" "provider" { + name = "cam-provider-test1" + meta_data = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48bWQ6RW50aXR5RGVzY3JpcHRvciBlbnRpdHlJRD0iaHR0cDovL3d3dy5va3RhLmNvbS9leGsxa3F4bWNqUW1HQURNeTM1NyIgeG1sbnM6bWQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSI+PG1kOklEUFNTT0Rlc2NyaXB0b3IgV2FudEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48bWQ6S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEb0RDQ0FvaWdBd0lCQWdJR0FXM0lTcExvTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdRTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHDQpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVDQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0dsa2VIVmxkblJoTVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwDQpibVp2UUc5cmRHRXVZMjl0TUI0WERURTVNVEF4TkRBek1qSXhNMW9YRFRJNU1UQXhOREF6TWpNeE0xb3dnWkF4Q3pBSkJnTlZCQVlUDQpBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFLDQpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJYVdSNGRXVjJkR0V4SERBYUJna3Foa2lHDQo5dzBCQ1FFV0RXbHVabTlBYjJ0MFlTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2g4b3dqDQpZK2dQSUM3blQvNTduLzdmeXJzcDlHMXdxa2UxdXhjMHVrTndnQXozOVNpelY3QVhLMWRReTFLaThXWjJJMzFEczJkT0FNQ1FKR2pWDQpUWWNNbnA3KzhqUzNLdmxNUkRJamk5cmxuUi9vcnBvMll1RHVWby9jVzdidlRIS2h2REo1QWZRaWxzYlNPTXdUOWM2TVlYZGhBNVBwDQpzelFsK1UrdHJmcXUrdUorSER4SVQxdlhWaVI5YlY2SUFRSzZpbWZoc2wxWmVSUytjbVFVNEpjQWlYT0xtTnFVVWM2UkpxUzhrMW1mDQpBLzhmb2VyMGc3SG4xZDVXclpCc2gyUlR2Vzh1ZVdadHQ3dmh4QTlGdE5kSVlEcXJ0eElmMlZXcXhrSHM3WFZDSm5wTnJITVovT1BRDQpGY21YSGVxNlJJMlB3Q1RlOW8zZHZpM0hqeXBaOEl4dkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFHaHk1bG9nbGtTDQoyVHg2YS90MnF5VEx0YVV5cEwrNGhySGJoMVAweVVMc0NrSnFsM2wrWG9VZDZCY2FJaFNSVGFPQk95ODViL0UzelJ4K3JzQXJwTjVVDQp5ZThuUEM4a05PYW5vTk9wWnZvYmhpTzFlMFIvYmxEcnRBL0o5UlBwMWtmdlhmS2NSTTU3TlRCWXppTURlbnFQUTRFOWN1U2lGdFFxDQpJYmpIbThaM1B1YXgwRitldkZ3U1pJMDNCWXNISGw1d1EraEJBS3hTdTJINEZRdU93Zmpnb2EveEN6Z1NKYjJ2UXdEc1MxMk9mSkNiDQpSRm1ZL1VYZXQramFhdEVORktLZStZSUJpU0J2WG1adTN0MHN5NDZTNzlPVzBacXJ0NUh2bElsT2lpTFpaN1FZamxjM1kxeG1LZ1luDQpXM2M2WGZkdmhGWHo0ZDdkbWYvTUdpNGY0enM9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9tZDpLZXlEZXNjcmlwdG9yPjxtZDpOYW1lSURGb3JtYXQ+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQ8L21kOk5hbWVJREZvcm1hdD48bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzczwvbWQ6TmFtZUlERm9ybWF0PjxtZDpTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkeHVldnRhLm9rdGEuY29tL2FwcC9pZHh1ZW9yZzYzNzM1OF90ZXN0XzEvZXhrMWtxeG1jalFtR0FETXkzNTcvc3NvL3NhbWwiLz48bWQ6U2luZ2xlU2lnbk9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWR4dWV2dGEub2t0YS5jb20vYXBwL2lkeHVlb3JnNjM3MzU4X3Rlc3RfMS9leGsxa3F4bWNqUW1HQURNeTM1Ny9zc28vc2FtbCIvPjwvbWQ6SURQU1NPRGVzY3JpcHRvcj48L21kOkVudGl0eURlc2NyaXB0b3I+" + description = "test" +} + +data "tencentcloud_cam_saml_providers" "saml_providers" { + name = "${tencentcloud_cam_saml_provider.provider.id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_user_policy_attachments.go b/tencentcloud/data_source_tc_cam_user_policy_attachments.go new file mode 100644 index 0000000000..696b1ee410 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_user_policy_attachments.go @@ -0,0 +1,166 @@ +/* +Use this data source to query detailed information of CAM user policy attachments + +Example Usage + +```hcl +data "tencentcloud_cam_user_policy_attachments" "foo" { + user_id = "cam-test" + policy_id = "215153266" + policy_type = "QCS" + create_mode = 1 +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamUserPolicyAttachments() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamUserPolicyAttachmentsRead, + + Schema: map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of the attached CAM user to be queried.", + }, + "policy_id": { + Type: schema.TypeString, + Optional: true, + Description: "Id of CAM policy to be queried.", + }, + "create_mode": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validateAllowedIntValue([]int{1, 2}), + Description: "Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateAllowedStringValue(CAM_POLICY_CREATE_STRATEGY), + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "user_policy_attachment_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM user policy attachments. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Computed: true, + Description: "Id of CAM user.", + }, + "policy_id": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM user.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "The create time of the CAM user policy attachment.", + }, + "policy_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the policy.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamUserPolicyAttachmentsRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_user_policy_attachments.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + userId := d.Get("user_id").(string) + params["user_id"] = userId + if v, ok := d.GetOk("policy_id"); ok { + params["policy_id"] = uint64(v.(int)) + } + if v, ok := d.GetOk("policy_type"); ok { + params["policy_type"] = v.(string) + } + if v, ok := d.GetOk("create_mode"); ok { + params["create_mode"] = v.(int) + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var policyOfUsers []*cam.AttachPolicyInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeUserPolicyAttachmentsByFilter(ctx, params) + if e != nil { + return retryError(e) + } + policyOfUsers = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM user policy attachments failed, reason:%s\n", logId, err.Error()) + return err + } + policyOfUserList := make([]map[string]interface{}, 0, len(policyOfUsers)) + ids := make([]string, 0, len(policyOfUsers)) + for _, policy := range policyOfUsers { + mapping := map[string]interface{}{ + "user_id": userId, + "policy_id": strconv.Itoa(int((*policy.PolicyId))), + "create_time": *policy.AddTime, + "create_mode": *policy.CreateMode, + "policy_type": *policy.PolicyType, + "policy_name": *policy.PolicyName, + } + policyOfUserList = append(policyOfUserList, mapping) + ids = append(ids, userId+"#"+strconv.Itoa(int(*policy.PolicyId))) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("user_policy_attachment_list", policyOfUserList); e != nil { + log.Printf("[CRITAL]%s provider set CAM user polilcy attachment list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), policyOfUserList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_user_policy_attachments_test.go b/tencentcloud/data_source_tc_cam_user_policy_attachments_test.go new file mode 100644 index 0000000000..584366d269 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_user_policy_attachments_test.go @@ -0,0 +1,57 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamUserPolicyAttachmentsDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamUserPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamUserPolicyAttachmentsDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamUserPolicyAttachmentExists("tencentcloud_cam_user_policy_attachment.user_policy_attachment"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_user_policy_attachments.user_policy_attachments", "user_policy_attachment_list.#", "1"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_user_policy_attachments.user_policy_attachments", "user_policy_attachment_list.0.user_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_user_policy_attachments.user_policy_attachments", "user_policy_attachment_list.0.policy_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_user_policy_attachments.user_policy_attachments", "user_policy_attachment_list.0.policy_name"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_user_policy_attachments.user_policy_attachments", "user_policy_attachment_list.0.create_mode"), + ), + }, + }, + }) +} + +const testAccCamUserPolicyAttachmentsDataSource_basic = ` +resource "tencentcloud_cam_user" "user" { + name = "cam-user-testt" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} + +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test7" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +resource "tencentcloud_cam_user_policy_attachment" "user_policy_attachment" { + user_id = "${tencentcloud_cam_user.user.id}" + policy_id = "${tencentcloud_cam_policy.policy.id}" +} + +data "tencentcloud_cam_user_policy_attachments" "user_policy_attachments" { + user_id = "${tencentcloud_cam_user_policy_attachment.user_policy_attachment.user_id}" +} +` diff --git a/tencentcloud/data_source_tc_cam_users.go b/tencentcloud/data_source_tc_cam_users.go new file mode 100644 index 0000000000..3e1cc4c80d --- /dev/null +++ b/tencentcloud/data_source_tc_cam_users.go @@ -0,0 +1,221 @@ +/* +Use this data source to query detailed information of CAM users + +Example Usage + +```hcl +data "tencentcloud_cam_users" "foo" { + name = "cam-user-test" + remark = "test" + console_login = true + email = "1245@qq.com" + uin = 151252 + country_code = "86" + phone_num = 1215151516 + uid = 5043021 +} +``` +*/ +package tencentcloud + +import ( + "context" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func dataSourceTencentCloudCamUsers() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudCamUsersRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "Name of CAM user to be queried.", + }, + "remark": { + Type: schema.TypeString, + Optional: true, + Description: "Remark of the CAM user to be queried.", + }, + "phone_num": { + Type: schema.TypeString, + Optional: true, + Description: "Phone num of the CAM user to be queried.", + }, + "country_code": { + Type: schema.TypeString, + Optional: true, + Description: "Country code of the CAM user to be queried.", + }, + "email": { + Type: schema.TypeString, + Optional: true, + Description: "Email of the CAM user to be queried.", + }, + "uin": { + Type: schema.TypeInt, + Optional: true, + Description: "Uin of the CAM user to be queried.", + }, + "uid": { + Type: schema.TypeInt, + Optional: true, + Description: "Uid of the CAM user to be queried.", + }, + "console_login": { + Type: schema.TypeBool, + Optional: true, + Description: "Indicate whether the user can login in.", + }, + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + "user_list": { + Type: schema.TypeList, + Computed: true, + Description: "A list of CAM users. Each element contains the following attributes:", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of CAM user.", + }, + "remark": { + Type: schema.TypeString, + Computed: true, + Description: "Remark of the CAM user.", + }, + "phone_num": { + Type: schema.TypeString, + Computed: true, + Description: "Phone num of the CAM user.", + }, + "country_code": { + Type: schema.TypeString, + Computed: true, + Description: "Country code of the CAM user.", + }, + "email": { + Type: schema.TypeString, + Computed: true, + Description: "Email of the CAM user.", + }, + "uin": { + Type: schema.TypeInt, + Computed: true, + Description: "Uin of the CAM user.", + }, + "uid": { + Type: schema.TypeInt, + Computed: true, + Description: "Uid of the CAM user.", + }, + "console_login": { + Type: schema.TypeBool, + Optional: true, + Description: "Indicate whether the user can login in.", + }, + }, + }, + }, + }, + } +} + +func dataSourceTencentCloudCamUsersRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("data_source.tencentcloud_cam_users.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + params := make(map[string]interface{}) + if v, ok := d.GetOk("name"); ok { + params["name"] = v.(string) + } + if v, ok := d.GetOk("uin"); ok { + params["uin"] = v.(int) + } + if v, ok := d.GetOk("remark"); ok { + params["remark"] = v.(string) + } + if v, ok := d.GetOk("uid"); ok { + params["uid"] = v.(int) + } + if v, ok := d.GetOk("phone_num"); ok { + params["phone_num"] = v.(string) + } + if v, ok := d.GetOk("country_code"); ok { + params["countryCode"] = v.(string) + } + if v, ok := d.GetOk("email"); ok { + params["email"] = v.(string) + } + if v, ok := d.GetOkExists("console_login"); ok { + consoleLogin := v.(bool) + if consoleLogin { + params["console_login"] = 1 + } else { + params["console_login"] = 0 + } + } + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var users []*cam.SubAccountInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + results, e := camService.DescribeUsersByFilter(ctx, params) + if e != nil { + return retryError(e) + } + users = results + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM users failed, reason:%s\n", logId, err.Error()) + return err + } + userList := make([]map[string]interface{}, 0, len(users)) + ids := make([]string, 0, len(users)) + for _, user := range users { + mapping := map[string]interface{}{ + "uin": int(*user.Uin), + "uid": int(*user.Uid), + "name": *user.Name, + "remark": *user.Remark, + "phone_num": *user.PhoneNum, + "country_code": *user.CountryCode, + "email": *user.Email, + } + if int(*user.ConsoleLogin) == 1 { + mapping["console_login"] = true + } else { + mapping["console_login"] = false + } + userList = append(userList, mapping) + ids = append(ids, *user.Name) + } + + d.SetId(dataResourceIdsHash(ids)) + if e := d.Set("user_list", userList); e != nil { + log.Printf("[CRITAL]%s provider set CAM user list fail, reason:%s\n", logId, e.Error()) + return e + } + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := writeToFile(output.(string), userList); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/data_source_tc_cam_users_test.go b/tencentcloud/data_source_tc_cam_users_test.go new file mode 100644 index 0000000000..b863b08d35 --- /dev/null +++ b/tencentcloud/data_source_tc_cam_users_test.go @@ -0,0 +1,50 @@ +package tencentcloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccTencentCloudCamUsersDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamUserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamUsersDataSource_basic, + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckCamUserExists("tencentcloud_cam_user.user"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.#", "1"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.0.remark", "test"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.0.name", "cam-user-tests"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.0.console_login", "true"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.0.phone_num", "13631555963"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.0.country_code", "86"), + resource.TestCheckResourceAttr("data.tencentcloud_cam_users.users", "user_list.0.email", "1234@qq.com"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_users.users", "user_list.0.uin"), + resource.TestCheckResourceAttrSet("data.tencentcloud_cam_users.users", "user_list.0.uid"), + ), + }, + }, + }) +} + +const testAccCamUsersDataSource_basic = ` +resource "tencentcloud_cam_user" "user" { + name = "cam-user-tests" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} + +data "tencentcloud_cam_users" "users" { + name = "${tencentcloud_cam_user.user.id}" +} +` diff --git a/tencentcloud/extension_cam.go b/tencentcloud/extension_cam.go new file mode 100644 index 0000000000..789c435ba4 --- /dev/null +++ b/tencentcloud/extension_cam.go @@ -0,0 +1,13 @@ +package tencentcloud + +const PAGE_ITEM = 200 + +const ( + CAM_POLICY_CREATE_STRATEGY_CUSTOM = "User" + CAM_POLICY_CREATE_STRATEGY_PRESET = "QCS" +) + +var CAM_POLICY_CREATE_STRATEGY = []string{ + CAM_POLICY_CREATE_STRATEGY_CUSTOM, + CAM_POLICY_CREATE_STRATEGY_PRESET, +} diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 049f8106df..753edd31a1 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -24,6 +24,15 @@ Data Sources tencentcloud_as_scaling_groups tencentcloud_as_scaling_policies tencentcloud_availability_zones + tencentcloud_cam_roles + tencentcloud_cam_role_policy_attachments + tencentcloud_cam_policies + tencentcloud_cam_users + tencentcloud_cam_user_policy_attachments + tencentcloud_cam_groups + tencentcloud_cam_group_policy_attachments + tencentcloud_cam_group_memberships + tencentcloud_cam_saml_providers tencentcloud_cbs_snapshots tencentcloud_cbs_storages tencentcloud_ccn_bandwidth_limits @@ -91,6 +100,17 @@ AS Resources tencentcloud_as_lifecycle_hook tencentcloud_as_notification +CAM Resources + tencentcloud_cam_role + tencentcloud_cam_role_policy_attachment + tencentcloud_cam_policy + tencentcloud_cam_user + tencentcloud_cam_user_policy_attachment + tencentcloud_cam_group + tencentcloud_cam_group_policy_attachment + tencentcloud_cam_group_membership + tencentcloud_cam_saml_provider + CBS Resources tencentcloud_cbs_storage tencentcloud_cbs_storage_attachment @@ -222,137 +242,155 @@ func Provider() *schema.Provider { }, DataSourcesMap: map[string]*schema.Resource{ - "tencentcloud_availability_zones": dataSourceTencentCloudAvailabilityZones(), - "tencentcloud_eip": dataSourceTencentCloudEip(), - "tencentcloud_image": dataSourceTencentCloudSourceImages(), - "tencentcloud_instance_types": dataSourceInstanceTypes(), - "tencentcloud_vpc": dataSourceTencentCloudVpc(), - "tencentcloud_subnet": dataSourceTencentCloudSubnet(), - "tencentcloud_route_table": dataSourceTencentCloudRouteTable(), - "tencentcloud_security_group": dataSourceTencentCloudSecurityGroup(), - "tencentcloud_security_groups": dataSourceTencentCloudSecurityGroups(), - "tencentcloud_nats": dataSourceTencentCloudNats(), - "tencentcloud_dnats": dataSourceTencentCloudDnats(), - "tencentcloud_nat_gateways": dataSourceTencentCloudNatGateways(), - "tencentcloud_container_clusters": dataSourceTencentCloudContainerClusters(), - "tencentcloud_container_cluster_instances": dataSourceTencentCloudContainerClusterInstances(), - "tencentcloud_mysql_backup_list": dataSourceTencentMysqlBackupList(), - "tencentcloud_mysql_zone_config": dataSourceTencentMysqlZoneConfig(), - "tencentcloud_mysql_parameter_list": dataSourceTencentCloudMysqlParameterList(), - "tencentcloud_mysql_instance": dataSourceTencentCloudMysqlInstance(), - "tencentcloud_cos_bucket_object": dataSourceTencentCloudCosBucketObject(), - "tencentcloud_cos_buckets": dataSourceTencentCloudCosBuckets(), - "tencentcloud_redis_zone_config": dataSourceTencentRedisZoneConfig(), - "tencentcloud_redis_instances": dataSourceTencentRedisInstances(), - "tencentcloud_as_scaling_configs": dataSourceTencentCloudAsScalingConfigs(), - "tencentcloud_as_scaling_groups": dataSourceTencentCloudAsScalingGroups(), - "tencentcloud_as_scaling_policies": dataSourceTencentCloudAsScalingPolicies(), - "tencentcloud_vpc_instances": dataSourceTencentCloudVpcInstances(), - "tencentcloud_vpc_subnets": dataSourceTencentCloudVpcSubnets(), - "tencentcloud_vpc_route_tables": dataSourceTencentCloudVpcRouteTables(), - "tencentcloud_ccn_instances": dataSourceTencentCloudCcnInstances(), - "tencentcloud_ccn_bandwidth_limits": dataSourceTencentCloudCcnBandwidthLimits(), - "tencentcloud_cbs_storages": dataSourceTencentCloudCbsStorages(), - "tencentcloud_cbs_snapshots": dataSourceTencentCloudCbsSnapshots(), - "tencentcloud_dc_instances": dataSourceTencentCloudDcInstances(), - "tencentcloud_clb_instances": dataSourceTencentCloudClbInstances(), - "tencentcloud_clb_listeners": dataSourceTencentCloudClbListeners(), - "tencentcloud_clb_listener_rules": dataSourceTencentCloudClbListenerRules(), - "tencentcloud_clb_attachments": dataSourceTencentCloudClbServerAttachments(), - "tencentcloud_clb_redirections": dataSourceTencentCloudClbRedirections(), - "tencentcloud_dcx_instances": dataSourceTencentCloudDcxInstances(), - "tencentcloud_mongodb_zone_config": dataSourceTencentCloudMongodbZoneConfig(), - "tencentcloud_mongodb_instances": dataSourceTencentCloudMongodbInstances(), - "tencentcloud_dc_gateway_instances": dataSourceTencentCloudDcGatewayInstances(), - "tencentcloud_dc_gateway_ccn_routes": dataSourceTencentCloudDcGatewayCCNRoutes(), - "tencentcloud_kubernetes_clusters": dataSourceTencentCloudKubernetesClusters(), - "tencentcloud_gaap_proxies": dataSourceTencentCloudGaapProxies(), - "tencentcloud_gaap_realservers": dataSourceTencentCloudGaapRealservers(), - "tencentcloud_gaap_layer4_listeners": dataSourceTencentCloudGaapLayer4Listeners(), - "tencentcloud_gaap_layer7_listeners": dataSourceTencentCloudGaapLayer7Listeners(), - "tencentcloud_gaap_http_domains": dataSourceTencentCloudGaapHttpDomains(), - "tencentcloud_gaap_http_rules": dataSourceTencentCloudGaapHttpRules(), - "tencentcloud_gaap_security_policies": dataSourceTencentCloudGaapSecurityPolices(), - "tencentcloud_gaap_security_rules": dataSourceTencentCloudGaapSecurityRules(), - "tencentcloud_gaap_certificates": dataSourceTencentCloudGaapCertificates(), - "tencentcloud_ssl_certificates": dataSourceTencentCloudSslCertificates(), - "tencentcloud_instances": dataSourceTencentCloudInstances(), - "tencentcloud_placement_groups": dataSourceTencentCloudPlacementGroups(), - "tencentcloud_eips": dataSourceTencentCloudEips(), - "tencentcloud_key_pairs": dataSourceTencentCloudKeyPairs(), - "tencentcloud_enis": dataSourceTencentCloudEnis(), - "tencentcloud_reserved_instance_configs": dataSourceTencentCloudReservedInstanceConfigs(), - "tencentcloud_reserved_instances": dataSourceTencentCloudReservedInstances(), + "tencentcloud_availability_zones": dataSourceTencentCloudAvailabilityZones(), + "tencentcloud_eip": dataSourceTencentCloudEip(), + "tencentcloud_image": dataSourceTencentCloudSourceImages(), + "tencentcloud_instance_types": dataSourceInstanceTypes(), + "tencentcloud_vpc": dataSourceTencentCloudVpc(), + "tencentcloud_subnet": dataSourceTencentCloudSubnet(), + "tencentcloud_route_table": dataSourceTencentCloudRouteTable(), + "tencentcloud_security_group": dataSourceTencentCloudSecurityGroup(), + "tencentcloud_security_groups": dataSourceTencentCloudSecurityGroups(), + "tencentcloud_nats": dataSourceTencentCloudNats(), + "tencentcloud_dnats": dataSourceTencentCloudDnats(), + "tencentcloud_nat_gateways": dataSourceTencentCloudNatGateways(), + "tencentcloud_container_clusters": dataSourceTencentCloudContainerClusters(), + "tencentcloud_container_cluster_instances": dataSourceTencentCloudContainerClusterInstances(), + "tencentcloud_mysql_backup_list": dataSourceTencentMysqlBackupList(), + "tencentcloud_mysql_zone_config": dataSourceTencentMysqlZoneConfig(), + "tencentcloud_mysql_parameter_list": dataSourceTencentCloudMysqlParameterList(), + "tencentcloud_mysql_instance": dataSourceTencentCloudMysqlInstance(), + "tencentcloud_cos_bucket_object": dataSourceTencentCloudCosBucketObject(), + "tencentcloud_cos_buckets": dataSourceTencentCloudCosBuckets(), + "tencentcloud_redis_zone_config": dataSourceTencentRedisZoneConfig(), + "tencentcloud_redis_instances": dataSourceTencentRedisInstances(), + "tencentcloud_as_scaling_configs": dataSourceTencentCloudAsScalingConfigs(), + "tencentcloud_as_scaling_groups": dataSourceTencentCloudAsScalingGroups(), + "tencentcloud_as_scaling_policies": dataSourceTencentCloudAsScalingPolicies(), + "tencentcloud_vpc_instances": dataSourceTencentCloudVpcInstances(), + "tencentcloud_vpc_subnets": dataSourceTencentCloudVpcSubnets(), + "tencentcloud_vpc_route_tables": dataSourceTencentCloudVpcRouteTables(), + "tencentcloud_ccn_instances": dataSourceTencentCloudCcnInstances(), + "tencentcloud_ccn_bandwidth_limits": dataSourceTencentCloudCcnBandwidthLimits(), + "tencentcloud_cbs_storages": dataSourceTencentCloudCbsStorages(), + "tencentcloud_cbs_snapshots": dataSourceTencentCloudCbsSnapshots(), + "tencentcloud_dc_instances": dataSourceTencentCloudDcInstances(), + "tencentcloud_clb_instances": dataSourceTencentCloudClbInstances(), + "tencentcloud_clb_listeners": dataSourceTencentCloudClbListeners(), + "tencentcloud_clb_listener_rules": dataSourceTencentCloudClbListenerRules(), + "tencentcloud_clb_attachments": dataSourceTencentCloudClbServerAttachments(), + "tencentcloud_clb_redirections": dataSourceTencentCloudClbRedirections(), + "tencentcloud_dcx_instances": dataSourceTencentCloudDcxInstances(), + "tencentcloud_mongodb_zone_config": dataSourceTencentCloudMongodbZoneConfig(), + "tencentcloud_mongodb_instances": dataSourceTencentCloudMongodbInstances(), + "tencentcloud_dc_gateway_instances": dataSourceTencentCloudDcGatewayInstances(), + "tencentcloud_dc_gateway_ccn_routes": dataSourceTencentCloudDcGatewayCCNRoutes(), + "tencentcloud_kubernetes_clusters": dataSourceTencentCloudKubernetesClusters(), + "tencentcloud_gaap_proxies": dataSourceTencentCloudGaapProxies(), + "tencentcloud_gaap_realservers": dataSourceTencentCloudGaapRealservers(), + "tencentcloud_gaap_layer4_listeners": dataSourceTencentCloudGaapLayer4Listeners(), + "tencentcloud_gaap_layer7_listeners": dataSourceTencentCloudGaapLayer7Listeners(), + "tencentcloud_gaap_http_domains": dataSourceTencentCloudGaapHttpDomains(), + "tencentcloud_gaap_http_rules": dataSourceTencentCloudGaapHttpRules(), + "tencentcloud_gaap_security_policies": dataSourceTencentCloudGaapSecurityPolices(), + "tencentcloud_gaap_security_rules": dataSourceTencentCloudGaapSecurityRules(), + "tencentcloud_gaap_certificates": dataSourceTencentCloudGaapCertificates(), + "tencentcloud_ssl_certificates": dataSourceTencentCloudSslCertificates(), + "tencentcloud_instances": dataSourceTencentCloudInstances(), + "tencentcloud_placement_groups": dataSourceTencentCloudPlacementGroups(), + "tencentcloud_eips": dataSourceTencentCloudEips(), + "tencentcloud_key_pairs": dataSourceTencentCloudKeyPairs(), + "tencentcloud_enis": dataSourceTencentCloudEnis(), + "tencentcloud_cam_roles": dataSourceTencentCloudCamRoles(), + "tencentcloud_cam_users": dataSourceTencentCloudCamUsers(), + "tencentcloud_cam_groups": dataSourceTencentCloudCamGroups(), + "tencentcloud_cam_group_memberships": dataSourceTencentCloudCamGroupMemberships(), + "tencentcloud_cam_policies": dataSourceTencentCloudCamPolicies(), + "tencentcloud_cam_role_policy_attachments": dataSourceTencentCloudCamRolePolicyAttachments(), + "tencentcloud_cam_user_policy_attachments": dataSourceTencentCloudCamUserPolicyAttachments(), + "tencentcloud_cam_group_policy_attachments": dataSourceTencentCloudCamGroupPolicyAttachments(), + "tencentcloud_cam_saml_providers": dataSourceTencentCloudCamSAMLProviders(), + "tencentcloud_reserved_instance_configs": dataSourceTencentCloudReservedInstanceConfigs(), + "tencentcloud_reserved_instances": dataSourceTencentCloudReservedInstances(), }, ResourcesMap: map[string]*schema.Resource{ - "tencentcloud_alb_server_attachment": resourceTencentCloudAlbServerAttachment(), - "tencentcloud_cbs_snapshot": resourceTencentCloudCbsSnapshot(), - "tencentcloud_cbs_snapshot_policy": resourceTencentCloudCbsSnapshotPolicy(), - "tencentcloud_cbs_storage": resourceTencentCloudCbsStorage(), - "tencentcloud_cbs_storage_attachment": resourceTencentCloudCbsStorageAttachment(), - "tencentcloud_clb_instance": resourceTencentCloudClbInstance(), - "tencentcloud_clb_listener": resourceTencentCloudClbListener(), - "tencentcloud_clb_listener_rule": resourceTencentCloudClbListenerRule(), - "tencentcloud_clb_attachment": resourceTencentCloudClbServerAttachment(), - "tencentcloud_clb_redirection": resourceTencentCloudClbRedirection(), - "tencentcloud_container_cluster": resourceTencentCloudContainerCluster(), - "tencentcloud_container_cluster_instance": resourceTencentCloudContainerClusterInstance(), - "tencentcloud_dnat": resourceTencentCloudDnat(), - "tencentcloud_eip": resourceTencentCloudEip(), - "tencentcloud_eip_association": resourceTencentCloudEipAssociation(), - "tencentcloud_instance": resourceTencentCloudInstance(), - "tencentcloud_key_pair": resourceTencentCloudKeyPair(), - "tencentcloud_lb": resourceTencentCloudLB(), - "tencentcloud_nat_gateway": resourceTencentCloudNatGateway(), - "tencentcloud_route_entry": resourceTencentCloudRouteEntry(), - "tencentcloud_route_table_entry": resourceTencentCloudVpcRouteEntry(), - "tencentcloud_route_table": resourceTencentCloudVpcRouteTable(), - "tencentcloud_security_group": resourceTencentCloudSecurityGroup(), - "tencentcloud_security_group_rule": resourceTencentCloudSecurityGroupRule(), - "tencentcloud_subnet": resourceTencentCloudVpcSubnet(), - "tencentcloud_vpc": resourceTencentCloudVpcInstance(), - "tencentcloud_mysql_backup_policy": resourceTencentCloudMysqlBackupPolicy(), - "tencentcloud_mysql_account": resourceTencentCloudMysqlAccount(), - "tencentcloud_mysql_account_privilege": resourceTencentCloudMysqlAccountPrivilege(), - "tencentcloud_mysql_instance": resourceTencentCloudMysqlInstance(), - "tencentcloud_mysql_readonly_instance": resourceTencentCloudMysqlReadonlyInstance(), - "tencentcloud_cos_bucket": resourceTencentCloudCosBucket(), - "tencentcloud_cos_bucket_object": resourceTencentCloudCosBucketObject(), - "tencentcloud_redis_instance": resourceTencentCloudRedisInstance(), - "tencentcloud_redis_backup_config": resourceTencentCloudRedisBackupConfig(), - "tencentcloud_as_scaling_config": resourceTencentCloudAsScalingConfig(), - "tencentcloud_as_scaling_group": resourceTencentCloudAsScalingGroup(), - "tencentcloud_as_attachment": resourceTencentCloudAsAttachment(), - "tencentcloud_as_scaling_policy": resourceTencentCloudAsScalingPolicy(), - "tencentcloud_as_schedule": resourceTencentCloudAsSchedule(), - "tencentcloud_as_lifecycle_hook": resourceTencentCloudAsLifecycleHook(), - "tencentcloud_as_notification": resourceTencentCloudAsNotification(), - "tencentcloud_ccn": resourceTencentCloudCcn(), - "tencentcloud_ccn_attachment": resourceTencentCloudCcnAttachment(), - "tencentcloud_ccn_bandwidth_limit": resourceTencentCloudCcnBandwidthLimit(), - "tencentcloud_dcx": resourceTencentCloudDcxInstance(), - "tencentcloud_mongodb_instance": resourceTencentCloudMongodbInstance(), - "tencentcloud_mongodb_sharding_instance": resourceTencentCloudMongodbShardingInstance(), - "tencentcloud_dc_gateway": resourceTencentCloudDcGatewayInstance(), - "tencentcloud_dc_gateway_ccn_route": resourceTencentCloudDcGatewayCcnRouteInstance(), - "tencentcloud_kubernetes_cluster": resourceTencentCloudTkeCluster(), - "tencentcloud_kubernetes_scale_worker": resourceTencentCloudTkeScaleWorker(), - "tencentcloud_gaap_proxy": resourceTencentCloudGaapProxy(), - "tencentcloud_gaap_realserver": resourceTencentCloudGaapRealserver(), - "tencentcloud_gaap_layer4_listener": resourceTencentCloudGaapLayer4Listener(), - "tencentcloud_gaap_layer7_listener": resourceTencentCloudGaapLayer7Listener(), - "tencentcloud_gaap_http_domain": resourceTencentCloudGaapHttpDomain(), - "tencentcloud_gaap_http_rule": resourceTencentCloudGaapHttpRule(), - "tencentcloud_gaap_certificate": resourceTencentCloudGaapCertificate(), - "tencentcloud_gaap_security_policy": resourceTencentCloudGaapSecurityPolicy(), - "tencentcloud_gaap_security_rule": resourceTencentCloudGaapSecurityRule(), - "tencentcloud_ssl_certificate": resourceTencentCloudSslCertificate(), - "tencentcloud_security_group_lite_rule": resourceTencentCloudSecurityGroupLiteRule(), - "tencentcloud_placement_group": resourceTencentCloudPlacementGroup(), - "tencentcloud_eni": resourceTencentCloudEni(), - "tencentcloud_eni_attachment": resourceTencentCloudEniAttachment(), - "tencentcloud_reserved_instance": resourceTencentCloudReservedInstance(), + "tencentcloud_alb_server_attachment": resourceTencentCloudAlbServerAttachment(), + "tencentcloud_cbs_snapshot": resourceTencentCloudCbsSnapshot(), + "tencentcloud_cbs_snapshot_policy": resourceTencentCloudCbsSnapshotPolicy(), + "tencentcloud_cbs_storage": resourceTencentCloudCbsStorage(), + "tencentcloud_cbs_storage_attachment": resourceTencentCloudCbsStorageAttachment(), + "tencentcloud_clb_instance": resourceTencentCloudClbInstance(), + "tencentcloud_clb_listener": resourceTencentCloudClbListener(), + "tencentcloud_clb_listener_rule": resourceTencentCloudClbListenerRule(), + "tencentcloud_clb_attachment": resourceTencentCloudClbServerAttachment(), + "tencentcloud_clb_redirection": resourceTencentCloudClbRedirection(), + "tencentcloud_container_cluster": resourceTencentCloudContainerCluster(), + "tencentcloud_container_cluster_instance": resourceTencentCloudContainerClusterInstance(), + "tencentcloud_dnat": resourceTencentCloudDnat(), + "tencentcloud_eip": resourceTencentCloudEip(), + "tencentcloud_eip_association": resourceTencentCloudEipAssociation(), + "tencentcloud_instance": resourceTencentCloudInstance(), + "tencentcloud_key_pair": resourceTencentCloudKeyPair(), + "tencentcloud_lb": resourceTencentCloudLB(), + "tencentcloud_nat_gateway": resourceTencentCloudNatGateway(), + "tencentcloud_route_entry": resourceTencentCloudRouteEntry(), + "tencentcloud_route_table_entry": resourceTencentCloudVpcRouteEntry(), + "tencentcloud_route_table": resourceTencentCloudVpcRouteTable(), + "tencentcloud_security_group": resourceTencentCloudSecurityGroup(), + "tencentcloud_security_group_rule": resourceTencentCloudSecurityGroupRule(), + "tencentcloud_subnet": resourceTencentCloudVpcSubnet(), + "tencentcloud_vpc": resourceTencentCloudVpcInstance(), + "tencentcloud_mysql_backup_policy": resourceTencentCloudMysqlBackupPolicy(), + "tencentcloud_mysql_account": resourceTencentCloudMysqlAccount(), + "tencentcloud_mysql_account_privilege": resourceTencentCloudMysqlAccountPrivilege(), + "tencentcloud_mysql_instance": resourceTencentCloudMysqlInstance(), + "tencentcloud_mysql_readonly_instance": resourceTencentCloudMysqlReadonlyInstance(), + "tencentcloud_cos_bucket": resourceTencentCloudCosBucket(), + "tencentcloud_cos_bucket_object": resourceTencentCloudCosBucketObject(), + "tencentcloud_redis_instance": resourceTencentCloudRedisInstance(), + "tencentcloud_redis_backup_config": resourceTencentCloudRedisBackupConfig(), + "tencentcloud_as_scaling_config": resourceTencentCloudAsScalingConfig(), + "tencentcloud_as_scaling_group": resourceTencentCloudAsScalingGroup(), + "tencentcloud_as_attachment": resourceTencentCloudAsAttachment(), + "tencentcloud_as_scaling_policy": resourceTencentCloudAsScalingPolicy(), + "tencentcloud_as_schedule": resourceTencentCloudAsSchedule(), + "tencentcloud_as_lifecycle_hook": resourceTencentCloudAsLifecycleHook(), + "tencentcloud_as_notification": resourceTencentCloudAsNotification(), + "tencentcloud_ccn": resourceTencentCloudCcn(), + "tencentcloud_ccn_attachment": resourceTencentCloudCcnAttachment(), + "tencentcloud_ccn_bandwidth_limit": resourceTencentCloudCcnBandwidthLimit(), + "tencentcloud_dcx": resourceTencentCloudDcxInstance(), + "tencentcloud_mongodb_instance": resourceTencentCloudMongodbInstance(), + "tencentcloud_mongodb_sharding_instance": resourceTencentCloudMongodbShardingInstance(), + "tencentcloud_dc_gateway": resourceTencentCloudDcGatewayInstance(), + "tencentcloud_dc_gateway_ccn_route": resourceTencentCloudDcGatewayCcnRouteInstance(), + "tencentcloud_kubernetes_cluster": resourceTencentCloudTkeCluster(), + "tencentcloud_kubernetes_scale_worker": resourceTencentCloudTkeScaleWorker(), + "tencentcloud_gaap_proxy": resourceTencentCloudGaapProxy(), + "tencentcloud_gaap_realserver": resourceTencentCloudGaapRealserver(), + "tencentcloud_gaap_layer4_listener": resourceTencentCloudGaapLayer4Listener(), + "tencentcloud_gaap_layer7_listener": resourceTencentCloudGaapLayer7Listener(), + "tencentcloud_gaap_http_domain": resourceTencentCloudGaapHttpDomain(), + "tencentcloud_gaap_http_rule": resourceTencentCloudGaapHttpRule(), + "tencentcloud_gaap_certificate": resourceTencentCloudGaapCertificate(), + "tencentcloud_gaap_security_policy": resourceTencentCloudGaapSecurityPolicy(), + "tencentcloud_gaap_security_rule": resourceTencentCloudGaapSecurityRule(), + "tencentcloud_ssl_certificate": resourceTencentCloudSslCertificate(), + "tencentcloud_security_group_lite_rule": resourceTencentCloudSecurityGroupLiteRule(), + "tencentcloud_placement_group": resourceTencentCloudPlacementGroup(), + "tencentcloud_eni": resourceTencentCloudEni(), + "tencentcloud_eni_attachment": resourceTencentCloudEniAttachment(), + "tencentcloud_cam_role": resourceTencentCloudCamRole(), + "tencentcloud_cam_user": resourceTencentCloudCamUser(), + "tencentcloud_cam_policy": resourceTencentCloudCamPolicy(), + "tencentcloud_cam_role_policy_attachment": resourceTencentCloudCamRolePolicyAttachment(), + "tencentcloud_cam_user_policy_attachment": resourceTencentCloudCamUserPolicyAttachment(), + "tencentcloud_cam_group_policy_attachment": resourceTencentCloudCamGroupPolicyAttachment(), + "tencentcloud_cam_group": resourceTencentCloudCamGroup(), + "tencentcloud_cam_group_membership": resourceTencentCloudCamGroupMembership(), + "tencentcloud_cam_saml_provider": resourceTencentCloudCamSAMLProvider(), + "tencentcloud_reserved_instance": resourceTencentCloudReservedInstance(), }, ConfigureFunc: providerConfigure, diff --git a/tencentcloud/resource_tc_cam_group.go b/tencentcloud/resource_tc_cam_group.go new file mode 100644 index 0000000000..84577186a8 --- /dev/null +++ b/tencentcloud/resource_tc_cam_group.go @@ -0,0 +1,210 @@ +/* +Provides a resource to create a CAM group. + +Example Usage + +```hcl +resource "tencentcloud_cam_group" "foo" { + name = "cam-group-test" + remark = "test" +} +``` + +Import + +CAM group can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_group.foo 90496 +``` +*/ +package tencentcloud + +import ( + "fmt" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamGroupCreate, + Read: resourceTencentCloudCamGroupRead, + Update: resourceTencentCloudCamGroupUpdate, + Delete: resourceTencentCloudCamGroupDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of CAM group.", + }, + "remark": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the CAM group.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM group.", + }, + }, + } +} + +func resourceTencentCloudCamGroupCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group.create")() + + logId := getLogId(contextNil) + + request := cam.NewCreateGroupRequest() + request.GroupName = stringToPointer(d.Get("name").(string)) + if v, ok := d.GetOk("remark"); ok { + request.Remark = stringToPointer(v.(string)) + } + + var response *cam.CreateGroupResponse + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().CreateGroup(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM group failed, reason:%s\n", logId, err.Error()) + return err + } + if response.Response.GroupId == nil { + return fmt.Errorf("CAM group id is nil") + } + d.SetId(strconv.Itoa(int(*response.Response.GroupId))) + + return resourceTencentCloudCamGroupRead(d, meta) +} + +func resourceTencentCloudCamGroupRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group.read")() + + logId := getLogId(contextNil) + + groupId := d.Id() + request := cam.NewGetGroupRequest() + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + return e + } + groupIdInt64 := uint64(groupIdInt) + request.GroupId = &groupIdInt64 + var instance *cam.GetGroupResponse + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().GetGroup(request) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM group failed, reason:%s\n", logId, err.Error()) + return err + } + + d.Set("name", *instance.Response.GroupName) + d.Set("create_time", *instance.Response.CreateTime) + if instance.Response.Remark != nil { + d.Set("remark", *instance.Response.Remark) + } + return nil +} + +func resourceTencentCloudCamGroupUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group.update")() + + logId := getLogId(contextNil) + + groupId := d.Id() + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + return e + } + groupIdInt64 := uint64(groupIdInt) + request := cam.NewUpdateGroupRequest() + request.GroupId = &groupIdInt64 + changeFlag := false + + if d.HasChange("remark") { + request.Remark = stringToPointer(d.Get("remark").(string)) + changeFlag = true + + } + if d.HasChange("name") { + request.GroupName = stringToPointer(d.Get("name").(string)) + changeFlag = true + } + + if changeFlag { + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + response, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdateGroup(request) + + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update CAM group description failed, reason:%s\n", logId, err.Error()) + return err + } + } + + return resourceTencentCloudCamGroupRead(d, meta) +} + +func resourceTencentCloudCamGroupDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group.delete")() + + logId := getLogId(contextNil) + + groupId := d.Id() + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + return e + } + groupIdInt64 := uint64(groupIdInt) + request := cam.NewDeleteGroupRequest() + request.GroupId = &groupIdInt64 + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + _, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DeleteGroup(request) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM group failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_group_membership.go b/tencentcloud/resource_tc_cam_group_membership.go new file mode 100644 index 0000000000..326735c527 --- /dev/null +++ b/tencentcloud/resource_tc_cam_group_membership.go @@ -0,0 +1,267 @@ +/* +Provides a resource to create a CAM group membership. + +Example Usage + +```hcl +resource "tencentcloud_cam_group_membership" "foo" { + group_id = "12515263" + user_ids = ["cam-test","cam-test2"] +} +``` + +Import + +CAM group membership can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_group_membership.foo 12515263 +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" + errors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" +) + +func resourceTencentCloudCamGroupMembership() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamGroupMembershipCreate, + Read: resourceTencentCloudCamGroupMembershipRead, + Update: resourceTencentCloudCamGroupMembershipUpdate, + Delete: resourceTencentCloudCamGroupMembershipDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of CAM group.", + }, + "user_ids": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Id set of the CAM group members.", + }, + }, + } +} + +func resourceTencentCloudCamGroupMembershipCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_membership.create")() + + logId := getLogId(contextNil) + + groupId := d.Get("group_id").(string) + members := d.Get("user_ids").(*schema.Set).List() + err := addUsersToGroup(members, groupId, meta) + if err != nil { + log.Printf("[CRITAL]%s create CAM group membership failed, reason:%s\n", logId, err.Error()) + return err + } + d.SetId(groupId) + + return resourceTencentCloudCamGroupMembershipRead(d, meta) +} + +func resourceTencentCloudCamGroupMembershipRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_membership.read")() + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + groupId := d.Id() + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var members []*string + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeGroupMembershipById(ctx, groupId) + if e != nil { + return retryError(e) + } + members = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM role failed, reason:%s\n", logId, err.Error()) + return err + } + + d.Set("group_id", groupId) + d.Set("user_ids", members) + + return nil +} + +func resourceTencentCloudCamGroupMembershipUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_membership.update")() + + logId := getLogId(contextNil) + + groupId := d.Id() + + if d.HasChange("user_ids") { + o, n := d.GetChange("user_ids") + os := o.(*schema.Set) + ns := n.(*schema.Set) + add := ns.Difference(os).List() + remove := os.Difference(ns).List() + if len(remove) > 0 { + oErr := removeUsersFromGroup(remove, groupId, meta) + if oErr != nil { + log.Printf("[CRITAL]%s update CAM group membership failed, reason:%s\n", logId, oErr.Error()) + return oErr + } + } + if len(add) > 0 { + nErr := addUsersToGroup(add, groupId, meta) + if nErr != nil { + log.Printf("[CRITAL]%s update CAM group membership failed, reason:%s\n", logId, nErr.Error()) + return nErr + } + } + } + + return resourceTencentCloudCamGroupMembershipRead(d, meta) +} + +func resourceTencentCloudCamGroupMembershipDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_membership.delete")() + + logId := getLogId(contextNil) + groupId := d.Get("group_id").(string) + members := d.Get("user_ids").(*schema.Set).List() + err := removeUsersFromGroup(members, groupId, meta) + if err != nil { + log.Printf("[CRITAL]%s delete CAM group failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} + +func getUidFromName(name string, meta interface{}) (uid *uint64, errRet error) { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeUserById(ctx, name) + if e != nil { + return retryError(e) + } + uid = result.Response.Uid + return nil + }) + if err != nil { + errRet = err + } + return +} + +func addUsersToGroup(members []interface{}, groupId string, meta interface{}) error { + logId := getLogId(contextNil) + + request := cam.NewAddUserToGroupRequest() + request.Info = make([]*cam.GroupIdOfUidInfo, 0) + for _, member := range members { + var info cam.GroupIdOfUidInfo + //get uid from name + + uId, e := getUidFromName(member.(string), meta) + if e != nil { + return e + } + info.Uid = uId + groupIdInt, ee := strconv.Atoi(groupId) + if ee != nil { + return ee + } + groupIdInt64 := uint64(groupIdInt) + info.GroupId = &groupIdInt64 + request.Info = append(request.Info, &info) + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().AddUserToGroup(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM group membership failed, reason:%s\n", logId, err.Error()) + return err + } + return nil +} + +func removeUsersFromGroup(members []interface{}, groupId string, meta interface{}) error { + logId := getLogId(contextNil) + + request := cam.NewRemoveUserFromGroupRequest() + request.Info = make([]*cam.GroupIdOfUidInfo, 0) + for _, member := range members { + var info cam.GroupIdOfUidInfo + uId, e := getUidFromName(member.(string), meta) + if e != nil { + //notice case when user is deleted, the uin is not found, and the membership is removed in the user module when deleted + ee, ok := e.(*errors.TencentCloudSDKError) + if !ok { + return e + } + if ee.Code == "ResourceNotFound.UserNotExist" { + continue + } else { + return e + } + } + info.Uid = uId + groupIdInt, eee := strconv.Atoi(groupId) + if eee != nil { + return eee + } + groupIdInt64 := uint64(groupIdInt) + info.GroupId = &groupIdInt64 + request.Info = append(request.Info, &info) + } + //no exist user need to remove, then return + if len(request.Info) == 0 { + return nil + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().RemoveUserFromGroup(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM group membership failed, reason:%s\n", logId, err.Error()) + return err + } + return nil +} diff --git a/tencentcloud/resource_tc_cam_group_membership_test.go b/tencentcloud/resource_tc_cam_group_membership_test.go new file mode 100644 index 0000000000..e743e4feb3 --- /dev/null +++ b/tencentcloud/resource_tc_cam_group_membership_test.go @@ -0,0 +1,131 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamGroupMembership_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamGroupMembershipDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamGroupMembership_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamGroupMembershipExists("tencentcloud_cam_group_membership.group_membership_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_group_membership.group_membership_basic", "group_id"), + resource.TestCheckResourceAttr("tencentcloud_cam_group_membership.group_membership_basic", "user_ids.#", "1"), + ), + }, { + Config: testAccCamGroupMembership_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamGroupMembershipExists("tencentcloud_cam_group_membership.group_membership_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_group_membership.group_membership_basic", "group_id"), + resource.TestCheckResourceAttr("tencentcloud_cam_group_membership.group_membership_basic", "user_ids.#", "1"), + ), + }, + { + ResourceName: "tencentcloud_cam_group_membership.group_membership_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamGroupMembershipDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_group_membership" { + continue + } + + _, err := camService.DescribeGroupMembershipById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM group membership still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamGroupMembershipExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM group %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM group id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeGroupMembershipById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamGroupMembership_basic = ` +resource "tencentcloud_cam_group" "group_basic" { + name = "cam-group-membership-test" + remark = "test" +} + +resource "tencentcloud_cam_user" "foo" { + name = "cam-user-test2" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} + +resource "tencentcloud_cam_group_membership" "group_membership_basic" { + group_id = "${tencentcloud_cam_group.group_basic.id}" + user_ids = ["${tencentcloud_cam_user.foo.id}",] +} +` + +const testAccCamGroupMembership_update = ` +resource "tencentcloud_cam_group" "group_basic" { + name = "cam-group-membership-test" + remark = "test" +} + +resource "tencentcloud_cam_user" "user_basic" { + name = "cam-user-testj" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} + +resource "tencentcloud_cam_group_membership" "group_membership_basic" { + group_id = "${tencentcloud_cam_group.group_basic.id}" + user_ids = ["${tencentcloud_cam_user.user_basic.id}"] +} +` diff --git a/tencentcloud/resource_tc_cam_group_policy_attachment.go b/tencentcloud/resource_tc_cam_group_policy_attachment.go new file mode 100644 index 0000000000..2fa57f1881 --- /dev/null +++ b/tencentcloud/resource_tc_cam_group_policy_attachment.go @@ -0,0 +1,171 @@ +/* +Provides a resource to create a CAM group policy attachment. + +Example Usage + +```hcl +resource "tencentcloud_cam_group_attachment" "foo" { + group_id = "12515263" + policy_id = "26800353" +} +``` + +Import + +CAM group policy attachment can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_group_attachment.foo 12515263#26800353 +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamGroupPolicyAttachment() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamGroupPolicyAttachmentCreate, + Read: resourceTencentCloudCamGroupPolicyAttachmentRead, + Delete: resourceTencentCloudCamGroupPolicyAttachmentDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the attached CAM group.", + }, + "policy_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the policy.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of Creation of the CAM group policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeBool, + Computed: true, + Description: "Type of the policy strategy. 'Group' means customer strategy and 'QCS' means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM group policy attachment.", + }, + "policy_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the policy.", + }, + }, + } +} + +func resourceTencentCloudCamGroupPolicyAttachmentCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_policy_attachment.create")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + groupId := d.Get("group_id").(string) + policyId := d.Get("policy_id").(string) + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + e := camService.AddGroupPolicyAttachment(ctx, groupId, policyId) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM group policy attachment failed, reason:%s\n", logId, err.Error()) + return err + } + + d.SetId(groupId + "#" + policyId) + + return resourceTencentCloudCamGroupPolicyAttachmentRead(d, meta) +} + +func resourceTencentCloudCamGroupPolicyAttachmentRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_policy_attachment.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + groupPolicyAttachmentId := d.Id() + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var instance *cam.AttachPolicyInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeGroupPolicyAttachmentById(ctx, groupPolicyAttachmentId) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM group policy attachment failed, reason:%s\n", logId, err.Error()) + return err + } + //split id + groupId, policyId, e := camService.decodeCamPolicyAttachmentId(groupPolicyAttachmentId) + if e != nil { + return e + } + d.Set("group_id", groupId) + d.Set("policy_id", strconv.Itoa(int(policyId))) + d.Set("policy_name", *instance.PolicyName) + d.Set("create_time", *instance.AddTime) + d.Set("create_mode", int(*instance.CreateMode)) + d.Set("policy_type", *instance.PolicyType) + return nil +} + +func resourceTencentCloudCamGroupPolicyAttachmentDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_group_policy_attachment.delete")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + groupPolicyAttachmentId := d.Id() + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + e := camService.DeleteGroupPolicyAttachmentById(ctx, groupPolicyAttachmentId) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM group policy attachment failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_group_policy_attachment_test.go b/tencentcloud/resource_tc_cam_group_policy_attachment_test.go new file mode 100644 index 0000000000..91b1445d27 --- /dev/null +++ b/tencentcloud/resource_tc_cam_group_policy_attachment_test.go @@ -0,0 +1,94 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamGroupPolicyAttachment_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamGroupPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamGroupPolicyAttachment_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamGroupPolicyAttachmentExists("tencentcloud_cam_group_policy_attachment.group_policy_attachment_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_group_policy_attachment.group_policy_attachment_basic", "group_id"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_group_policy_attachment.group_policy_attachment_basic", "policy_id"), + ), + }, + { + ResourceName: "tencentcloud_cam_group_policy_attachment.group_policy_attachment_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamGroupPolicyAttachmentDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_group_policy_attachment" { + continue + } + + _, err := camService.DescribeGroupPolicyAttachmentById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM group policy attachment still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamGroupPolicyAttachmentExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM group policy attachment %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM group policy attachment id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeGroupPolicyAttachmentById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamGroupPolicyAttachment_basic = ` +resource "tencentcloud_cam_group" "group" { + name = "cam-group-test2" + remark = "test" +} + +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test9" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +resource "tencentcloud_cam_group_policy_attachment" "group_policy_attachment_basic" { + group_id = "${tencentcloud_cam_group.group.id}" + policy_id = "${tencentcloud_cam_policy.policy.id}" +} +` diff --git a/tencentcloud/resource_tc_cam_group_test.go b/tencentcloud/resource_tc_cam_group_test.go new file mode 100644 index 0000000000..632c0d7de1 --- /dev/null +++ b/tencentcloud/resource_tc_cam_group_test.go @@ -0,0 +1,98 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamGroup_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamGroup_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamGroupExists("tencentcloud_cam_group.group_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_group.group_basic", "name", "cam-group-test1"), + + resource.TestCheckResourceAttr("tencentcloud_cam_group.group_basic", "remark", "test"), + ), + }, { + Config: testAccCamGroup_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamGroupExists("tencentcloud_cam_group.group_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_group.group_basic", "name", "cam-group-test2"), + resource.TestCheckResourceAttr("tencentcloud_cam_group.group_basic", "remark", "test-update"), + ), + }, + { + ResourceName: "tencentcloud_cam_group.group_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamGroupDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_group" { + continue + } + + _, err := camService.DescribeGroupById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM group still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamGroupExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM group %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM group id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeGroupById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamGroup_basic = ` +resource "tencentcloud_cam_group" "group_basic" { + name = "cam-group-test1" + remark = "test" +} +` + +const testAccCamGroup_update = ` +resource "tencentcloud_cam_group" "group_basic" { + name = "cam-group-test2" + remark = "test-update" +} +` diff --git a/tencentcloud/resource_tc_cam_policy.go b/tencentcloud/resource_tc_cam_policy.go new file mode 100644 index 0000000000..1d06854c63 --- /dev/null +++ b/tencentcloud/resource_tc_cam_policy.go @@ -0,0 +1,262 @@ +/* +Provides a resource to create a CAM policy. + +Example Usage + +```hcl +resource "tencentcloud_cam_policy" "foo" { + name = "cam-policy-test" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} +``` + +Import + +CAM policy can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_policy.foo 26655801 +``` +*/ +package tencentcloud + +import ( + "fmt" + "log" + "strconv" + "strings" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamPolicyCreate, + Read: resourceTencentCloudCamPolicyRead, + Update: resourceTencentCloudCamPolicyUpdate, + Delete: resourceTencentCloudCamPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Name of CAM policy.", + }, + "document": { + Type: schema.TypeString, + Required: true, + Description: "Document of the CAM policy. The syntax refers to https://intl.cloud.tencent.com/document/product/598/10604. There are some notes when using this para in terraform: 1. The elements in JSON claimed supporting two types as `string` and `array` only support type `array`; 2. Terraform does not support the `root` syntax, when it appears, it must be replaced with the uin it stands for.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the CAM policy.", + }, + "type": { + Type: schema.TypeInt, + Computed: true, + Description: "Type of the policy strategy. 1 means customer strategy and 2 means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM policy.", + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "The last update time of the CAM policy.", + }, + }, + } +} + +func resourceTencentCloudCamPolicyCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_policy.create")() + + logId := getLogId(contextNil) + + name := d.Get("name").(string) + document := d.Get("document").(string) + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + documentErr := camService.PolicyDocumentForceCheck(document) + if documentErr != nil { + return documentErr + } + request := cam.NewCreatePolicyRequest() + request.PolicyName = &name + request.PolicyDocument = &document + if v, ok := d.GetOk("description"); ok { + request.Description = stringToPointer(v.(string)) + } + + var response *cam.CreatePolicyResponse + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().CreatePolicy(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM policy failed, reason:%s\n", logId, err.Error()) + return err + } + if response.Response.PolicyId == nil { + return fmt.Errorf("CAM policy id is nil") + } + d.SetId(strconv.Itoa(int(*response.Response.PolicyId))) + + return resourceTencentCloudCamPolicyRead(d, meta) +} + +func resourceTencentCloudCamPolicyRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_policy.read")() + + logId := getLogId(contextNil) + + policyId := d.Id() + request := cam.NewGetPolicyRequest() + policyIdInt, e := strconv.Atoi(policyId) + if e != nil { + return e + } + policyIdInt64 := uint64(policyIdInt) + request.PolicyId = &policyIdInt64 + var instance *cam.GetPolicyResponse + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().GetPolicy(request) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM policy failed, reason:%s\n", logId, err.Error()) + return err + } + + d.Set("name", *instance.Response.PolicyName) + //document with special change rule, the `\\/` must be replaced with `/` + d.Set("document", strings.Replace(*instance.Response.PolicyDocument, "\\/", "/", -1)) + d.Set("create_time", *instance.Response.AddTime) + d.Set("update_time", *instance.Response.UpdateTime) + d.Set("type", int(*instance.Response.Type)) + if instance.Response.Description != nil { + d.Set("description", *instance.Response.Description) + } + return nil +} + +func resourceTencentCloudCamPolicyUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_policy.update")() + + logId := getLogId(contextNil) + + policyId := d.Id() + policyIdInt, e := strconv.Atoi(policyId) + if e != nil { + return e + } + policyIdInt64 := uint64(policyIdInt) + request := cam.NewUpdatePolicyRequest() + request.PolicyId = &policyIdInt64 + changeFlag := false + + if d.HasChange("description") { + request.Description = stringToPointer(d.Get("description").(string)) + changeFlag = true + + } + if d.HasChange("name") { + request.PolicyName = stringToPointer(d.Get("name").(string)) + changeFlag = true + } + + if d.HasChange("document") { + o, n := d.GetChange("document") + flag, err := diffJson(o.(string), n.(string)) + if err != nil { + log.Printf("[CRITAL]%s update CAM policy document failed, reason:%s\n", logId, err.Error()) + return err + } + if flag { + document := d.Get("document").(string) + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + documentErr := camService.PolicyDocumentForceCheck(document) + if documentErr != nil { + return documentErr + } + request.PolicyDocument = &document + changeFlag = true + } + } + if changeFlag { + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + response, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdatePolicy(request) + + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update CAM policy description failed, reason:%s\n", logId, err.Error()) + return err + } + } + + return resourceTencentCloudCamPolicyRead(d, meta) +} + +func resourceTencentCloudCamPolicyDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_policy.delete")() + + logId := getLogId(contextNil) + + policyId := d.Id() + policyIdInt, e := strconv.Atoi(policyId) + if e != nil { + return e + } + policyIdInt64 := uint64(policyIdInt) + request := cam.NewDeletePolicyRequest() + request.PolicyId = []*uint64{&policyIdInt64} + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + _, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DeletePolicy(request) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM policy failed, reason:%s\n", logId, err.Error()) + return err + } + return nil +} diff --git a/tencentcloud/resource_tc_cam_policy_test.go b/tencentcloud/resource_tc_cam_policy_test.go new file mode 100644 index 0000000000..68597f5755 --- /dev/null +++ b/tencentcloud/resource_tc_cam_policy_test.go @@ -0,0 +1,99 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamPolicy_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamPolicy_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamPolicyExists("tencentcloud_cam_policy.policy_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_policy.policy_basic", "name", "cam-policy-test4"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_policy.policy_basic", "document"), + resource.TestCheckResourceAttr("tencentcloud_cam_policy.policy_basic", "description", "test"), + ), + }, { + Config: testAccCamPolicy_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamPolicyExists("tencentcloud_cam_policy.policy_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_policy.policy_basic", "name", "cam-policy-test2"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_policy.policy_basic", "document"), + ), + }, + { + ResourceName: "tencentcloud_cam_policy.policy_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamPolicyDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_policy" { + continue + } + + _, err := camService.DescribePolicyById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM policy still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamPolicyExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM policy %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM policy id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribePolicyById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamPolicy_basic = ` +resource "tencentcloud_cam_policy" "policy_basic" { + name = "cam-policy-test4" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} +` + +const testAccCamPolicy_update = ` +resource "tencentcloud_cam_policy" "policy_basic" { + name = "cam-policy-test2" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]},{\"action\":[\"name/cos:PutObject\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" +} +` diff --git a/tencentcloud/resource_tc_cam_role.go b/tencentcloud/resource_tc_cam_role.go new file mode 100644 index 0000000000..9fd76662ea --- /dev/null +++ b/tencentcloud/resource_tc_cam_role.go @@ -0,0 +1,288 @@ +/* +Provides a resource to create a CAM role. + +Example Usage + +```hcl +resource "tencentcloud_cam_role" "foo" { + name = "cam-role-test" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":\"name/sts:AssumeRole\",\"effect\":\"allow\",\"principal\":{\"qcs\":\"qcs::cam::uin/3374997817:uin/3374997817\"}}]}" + description = "test" + console_login = true +} +``` + +Import + +CAM role can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_role.foo 4611686018427733635 +``` +*/ +package tencentcloud + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamRole() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamRoleCreate, + Read: resourceTencentCloudCamRoleRead, + Update: resourceTencentCloudCamRoleUpdate, + Delete: resourceTencentCloudCamRoleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Name of CAM role.", + }, + "document": { + Type: schema.TypeString, + Required: true, + Description: "Document of the CAM role. The syntax refers to https://intl.cloud.tencent.com/document/product/598/10604. There are some notes when using this para in terraform: 1. The elements in json claimed supporting two types as `string` and `array` only support type `array`; 2. Terraform does not support the `root` syntax, when appears, it must be replaced with the uin it stands for.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the CAM role.", + }, + "console_login": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: "Indicade whether the CAM role can login or not.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM role.", + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "The last update time of the CAM role.", + }, + }, + } +} + +func resourceTencentCloudCamRoleCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role.create")() + + logId := getLogId(contextNil) + + name := d.Get("name").(string) + document := d.Get("document").(string) + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + documentErr := camService.PolicyDocumentForceCheck(document) + if documentErr != nil { + return documentErr + } + request := cam.NewCreateRoleRequest() + request.RoleName = &name + request.PolicyDocument = &document + if v, ok := d.GetOk("description"); ok { + request.Description = stringToPointer(v.(string)) + } + if v, ok := d.GetOkExists("console_login"); ok { + loginBool := v.(bool) + loginInt := uint64(1) + if !loginBool { + loginInt = uint64(0) + } + request.ConsoleLogin = &loginInt + } + + var response *cam.CreateRoleResponse + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().CreateRole(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM role failed, reason:%s\n", logId, err.Error()) + return err + } + if response.Response.RoleId == nil { + return fmt.Errorf("CAM role id is nil") + } + d.SetId(*response.Response.RoleId) + + return resourceTencentCloudCamRoleRead(d, meta) +} + +func resourceTencentCloudCamRoleRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + roleId := d.Id() + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var instance *cam.RoleInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeRoleById(ctx, roleId) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM role failed, reason:%s\n", logId, err.Error()) + return err + } + + d.Set("name", instance.RoleName) + d.Set("document", instance.PolicyDocument) + d.Set("create_time", instance.AddTime) + d.Set("update_time", instance.UpdateTime) + if instance.Description != nil { + d.Set("description", instance.Description) + } + + if instance.ConsoleLogin != nil { + if int(*instance.ConsoleLogin) == 1 { + d.Set("console_login", true) + } else { + d.Set("console_login", false) + } + } else { + d.Set("console_login", false) + } + return nil +} + +func resourceTencentCloudCamRoleUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role.update")() + + logId := getLogId(contextNil) + + d.Partial(true) + + roleId := d.Id() + + description := "" + if d.HasChange("description") { + if v, ok := d.GetOk("description"); ok { + description = v.(string) + } + mDescRequest := cam.NewUpdateRoleDescriptionRequest() + mDescRequest.Description = &description + mDescRequest.RoleId = &roleId + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + response, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdateRoleDescription(mDescRequest) + + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, mDescRequest.GetAction(), mDescRequest.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, mDescRequest.GetAction(), mDescRequest.ToJsonString(), response.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update CAM role description failed, reason:%s\n", logId, err.Error()) + return err + } + d.SetPartial("description") + } + document := "" + if d.HasChange("document") { + o, n := d.GetChange("document") + flag, err := diffJson(o.(string), n.(string)) + if err != nil { + log.Printf("[CRITAL]%s update CAM role document failed, reason:%s\n", logId, err.Error()) + return err + } + if flag { + document = d.Get("document").(string) + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + documentErr := camService.PolicyDocumentForceCheck(document) + if documentErr != nil { + return documentErr + } + mDocRequest := cam.NewUpdateAssumeRolePolicyRequest() + mDocRequest.PolicyDocument = &document + mDocRequest.RoleId = &roleId + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + response, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdateAssumeRolePolicy(mDocRequest) + + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, mDocRequest.GetAction(), mDocRequest.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, mDocRequest.GetAction(), mDocRequest.ToJsonString(), response.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update CAM role document failed, reason:%s\n", logId, err.Error()) + return err + } + d.SetPartial("document") + } + } + + d.Partial(false) + + return resourceTencentCloudCamRoleRead(d, meta) +} + +func resourceTencentCloudCamRoleDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role.delete")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + roleId := d.Id() + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + e := camService.DeleteRoleById(ctx, roleId) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM role failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_role_policy_attachment.go b/tencentcloud/resource_tc_cam_role_policy_attachment.go new file mode 100644 index 0000000000..9953d5b8ce --- /dev/null +++ b/tencentcloud/resource_tc_cam_role_policy_attachment.go @@ -0,0 +1,178 @@ +/* +Provides a resource to create a CAM role policy attachment. + +Example Usage + +```hcl +resource "tencentcloud_cam_role_attachment" "foo" { + group_id = "4611686018427922725" + policy_id = "26800353" +} +``` + +Import + +CAM role policy attachment can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_role_attachment.foo 4611686018427922725#26800353 +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamRolePolicyAttachment() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamRolePolicyAttachmentCreate, + Read: resourceTencentCloudCamRolePolicyAttachmentRead, + Delete: resourceTencentCloudCamRolePolicyAttachmentDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "role_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the attached CAM role.", + }, + "policy_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the policy.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of Creation of the CAM role policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeBool, + Computed: true, + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "The create time of the CAM role policy attachment.", + }, + "policy_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the policy.", + }, + }, + } +} + +func resourceTencentCloudCamRolePolicyAttachmentCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role_policy_attachment.create")() + + logId := getLogId(contextNil) + + roleId := d.Get("role_id").(string) + policyId, e := strconv.Atoi(d.Get("policy_id").(string)) + if e != nil { + return e + } + policyId64 := uint64(policyId) + request := cam.NewAttachRolePolicyRequest() + request.AttachRoleId = &roleId + request.PolicyId = &policyId64 + + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().AttachRolePolicy(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM role policy attachment failed, reason:%s\n", logId, err.Error()) + return err + } + + d.SetId(roleId + "#" + strconv.Itoa(policyId)) + + return resourceTencentCloudCamRolePolicyAttachmentRead(d, meta) +} + +func resourceTencentCloudCamRolePolicyAttachmentRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role_policy_attachment.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rolePolicyAttachmentId := d.Id() + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var instance *cam.AttachedPolicyOfRole + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeRolePolicyAttachmentById(ctx, rolePolicyAttachmentId) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM role policy attachment failed, reason:%s\n", logId, err.Error()) + return err + } + roleId, policyId, e := camService.decodeCamPolicyAttachmentId(rolePolicyAttachmentId) + if e != nil { + return e + } + d.Set("role_id", roleId) + d.Set("policy_id", strconv.Itoa(int(policyId))) + d.Set("policy_name", *instance.PolicyName) + d.Set("create_time", *instance.AddTime) + d.Set("create_mode", int(*instance.CreateMode)) + d.Set("policy_type", *instance.PolicyType) + return nil +} + +func resourceTencentCloudCamRolePolicyAttachmentDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_role_policy_attachment.delete")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rolePolicyAttachmentId := d.Id() + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + e := camService.DeleteRolePolicyAttachmentById(ctx, rolePolicyAttachmentId) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM role policy attachment failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_role_policy_attachment_test.go b/tencentcloud/resource_tc_cam_role_policy_attachment_test.go new file mode 100644 index 0000000000..3b5de674d6 --- /dev/null +++ b/tencentcloud/resource_tc_cam_role_policy_attachment_test.go @@ -0,0 +1,97 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamRolePolicyAttachment_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamRolePolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamRolePolicyAttachment_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamRolePolicyAttachmentExists("tencentcloud_cam_role_policy_attachment.role_policy_attachment_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_role_policy_attachment.role_policy_attachment_basic", "role_id"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_role_policy_attachment.role_policy_attachment_basic", "policy_id"), + ), + }, + { + ResourceName: "tencentcloud_cam_role_policy_attachment.role_policy_attachment_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamRolePolicyAttachmentDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_role_policy_attachment" { + continue + } + + _, err := camService.DescribeRolePolicyAttachmentById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM role policy attachment still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamRolePolicyAttachmentExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM role policy attachment %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM role policy attachment id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeRolePolicyAttachmentById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +//need to add policy resource definition +const testAccCamRolePolicyAttachment_basic = ` +resource "tencentcloud_cam_role" "role" { + name = "cam-role-test" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}}]}" + description = "test" + console_login = true +} + +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test2" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +resource "tencentcloud_cam_role_policy_attachment" "role_policy_attachment_basic" { + role_id = "${tencentcloud_cam_role.role.id}" + policy_id = "${tencentcloud_cam_policy.policy.id}" +} +` diff --git a/tencentcloud/resource_tc_cam_role_test.go b/tencentcloud/resource_tc_cam_role_test.go new file mode 100644 index 0000000000..a40437cb71 --- /dev/null +++ b/tencentcloud/resource_tc_cam_role_test.go @@ -0,0 +1,100 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamRole_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamRoleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamRole_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamRoleExists("tencentcloud_cam_role.role_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_role.role_basic", "name"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_role.role_basic", "document"), + ), + }, { + Config: testAccCamRole_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamRoleExists("tencentcloud_cam_role.role_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_role.role_basic", "name"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_role.role_basic", "document"), + ), + }, + { + ResourceName: "tencentcloud_cam_role.role_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamRoleDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_role" { + continue + } + + _, err := camService.DescribeRoleById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM role still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamRoleExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM role %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM role id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeRoleById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamRole_basic = ` +resource "tencentcloud_cam_role" "role_basic" { + name = "cam-role-test1" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}}]}" + description = "test" + console_login = true +} +` + +const testAccCamRole_update = ` +resource "tencentcloud_cam_role" "role_basic" { + name = "cam-role-test1" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}},{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"principal\":{\"qcs\":[\"qcs::cam::uin/100009461222:uin/100009461222\"]}}]}" + console_login = false +} +` diff --git a/tencentcloud/resource_tc_cam_saml_provider.go b/tencentcloud/resource_tc_cam_saml_provider.go new file mode 100644 index 0000000000..2d84add04b --- /dev/null +++ b/tencentcloud/resource_tc_cam_saml_provider.go @@ -0,0 +1,215 @@ +/* +Provides a resource to create a CAM SAML provider. + +Example Usage + +```hcl +resource "tencentcloud_cam_saml_provider" "saml_provider_basic" { + name = "cam-saml-provider-test" + meta_data = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48bWQ6RW50aXR5RGVzY3JpcHRvciBlbnRpdHlJRD0iaHR0cDovL3d3dy5va3RhLmNvbS9leGsxa3F4bWNqUW1HQURNeTM1NyIgeG1sbnM6bWQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSI+PG1kOklEUFNTT0Rlc2NyaXB0b3IgV2FudEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48bWQ6S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEb0RDQ0FvaWdBd0lCQWdJR0FXM0lTcExvTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdRTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHDQpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVDQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0dsa2VIVmxkblJoTVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwDQpibVp2UUc5cmRHRXVZMjl0TUI0WERURTVNVEF4TkRBek1qSXhNMW9YRFRJNU1UQXhOREF6TWpNeE0xb3dnWkF4Q3pBSkJnTlZCQVlUDQpBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFLDQpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJYVdSNGRXVjJkR0V4SERBYUJna3Foa2lHDQo5dzBCQ1FFV0RXbHVabTlBYjJ0MFlTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2g4b3dqDQpZK2dQSUM3blQvNTduLzdmeXJzcDlHMXdxa2UxdXhjMHVrTndnQXozOVNpelY3QVhLMWRReTFLaThXWjJJMzFEczJkT0FNQ1FKR2pWDQpUWWNNbnA3KzhqUzNLdmxNUkRJamk5cmxuUi9vcnBvMll1RHVWby9jVzdidlRIS2h2REo1QWZRaWxzYlNPTXdUOWM2TVlYZGhBNVBwDQpzelFsK1UrdHJmcXUrdUorSER4SVQxdlhWaVI5YlY2SUFRSzZpbWZoc2wxWmVSUytjbVFVNEpjQWlYT0xtTnFVVWM2UkpxUzhrMW1mDQpBLzhmb2VyMGc3SG4xZDVXclpCc2gyUlR2Vzh1ZVdadHQ3dmh4QTlGdE5kSVlEcXJ0eElmMlZXcXhrSHM3WFZDSm5wTnJITVovT1BRDQpGY21YSGVxNlJJMlB3Q1RlOW8zZHZpM0hqeXBaOEl4dkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFHaHk1bG9nbGtTDQoyVHg2YS90MnF5VEx0YVV5cEwrNGhySGJoMVAweVVMc0NrSnFsM2wrWG9VZDZCY2FJaFNSVGFPQk95ODViL0UzelJ4K3JzQXJwTjVVDQp5ZThuUEM4a05PYW5vTk9wWnZvYmhpTzFlMFIvYmxEcnRBL0o5UlBwMWtmdlhmS2NSTTU3TlRCWXppTURlbnFQUTRFOWN1U2lGdFFxDQpJYmpIbThaM1B1YXgwRitldkZ3U1pJMDNCWXNISGw1d1EraEJBS3hTdTJINEZRdU93Zmpnb2EveEN6Z1NKYjJ2UXdEc1MxMk9mSkNiDQpSRm1ZL1VYZXQramFhdEVORktLZStZSUJpU0J2WG1adTN0MHN5NDZTNzlPVzBacXJ0NUh2bElsT2lpTFpaN1FZamxjM1kxeG1LZ1luDQpXM2M2WGZkdmhGWHo0ZDdkbWYvTUdpNGY0enM9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9tZDpLZXlEZXNjcmlwdG9yPjxtZDpOYW1lSURGb3JtYXQ+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQ8L21kOk5hbWVJREZvcm1hdD48bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzczwvbWQ6TmFtZUlERm9ybWF0PjxtZDpTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkeHVldnRhLm9rdGEuY29tL2FwcC9pZHh1ZW9yZzYzNzM1OF90ZXN0XzEvZXhrMWtxeG1jalFtR0FETXkzNTcvc3NvL3NhbWwiLz48bWQ6U2luZ2xlU2lnbk9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWR4dWV2dGEub2t0YS5jb20vYXBwL2lkeHVlb3JnNjM3MzU4X3Rlc3RfMS9leGsxa3F4bWNqUW1HQURNeTM1Ny9zc28vc2FtbCIvPjwvbWQ6SURQU1NPRGVzY3JpcHRvcj48L21kOkVudGl0eURlc2NyaXB0b3I+" + description = "test" +} +``` + +Import + +CAM SAML provider can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_saml_provider.foo cam-SAML-provider-test +``` +*/ +package tencentcloud + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamSAMLProvider() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamSAMLProviderCreate, + Read: resourceTencentCloudCamSAMLProviderRead, + Update: resourceTencentCloudCamSAMLProviderUpdate, + Delete: resourceTencentCloudCamSAMLProviderDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of CAM SAML provider.", + }, + "description": { + Type: schema.TypeString, + Required: true, + Description: "The description of the CAM SAML provider.", + }, + "meta_data": { + Type: schema.TypeString, + Required: true, + Description: "The meta data document of the CAM SAML provider.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "The create time of the CAM SAML provider.", + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "The last update time of the CAM SAML provider.", + }, + "provider_arn": { + Type: schema.TypeString, + Computed: true, + Description: "The arn of the CAM SAML provider.", + }, + }, + } +} + +func resourceTencentCloudCamSAMLProviderCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_saml_provider.create")() + + logId := getLogId(contextNil) + + request := cam.NewCreateSAMLProviderRequest() + request.Name = stringToPointer(d.Get("name").(string)) + request.SAMLMetadataDocument = stringToPointer(d.Get("meta_data").(string)) + //special check function + if v, ok := d.GetOk("description"); ok { + request.Description = stringToPointer(v.(string)) + } + + var response *cam.CreateSAMLProviderResponse + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().CreateSAMLProvider(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create CAM SAML provider failed, reason:%s\n", logId, err.Error()) + return err + } + if response.Response.ProviderArn == nil { + return fmt.Errorf("CAM SAML provider id is nil") + } + d.SetId(d.Get("name").(string)) + d.Set("provider_arn", *response.Response.ProviderArn) + + return resourceTencentCloudCamSAMLProviderRead(d, meta) +} + +func resourceTencentCloudCamSAMLProviderRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_saml_provider.read")() + + logId := getLogId(contextNil) + + SAMLProviderId := d.Id() + request := cam.NewGetSAMLProviderRequest() + request.Name = &SAMLProviderId + var instance *cam.GetSAMLProviderResponse + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().GetSAMLProvider(request) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM SAML provider failed, reason:%s\n", logId, err.Error()) + return err + } + + d.Set("name", *instance.Response.Name) + d.Set("create_time", *instance.Response.CreateTime) + d.Set("update_time", *instance.Response.ModifyTime) + d.Set("meta_data", *instance.Response.SAMLMetadata) + if instance.Response.Description != nil { + d.Set("description", *instance.Response.Description) + } + return nil +} + +func resourceTencentCloudCamSAMLProviderUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_saml_provider.update")() + + logId := getLogId(contextNil) + + SAMLProviderId := d.Id() + request := cam.NewUpdateSAMLProviderRequest() + request.Name = &SAMLProviderId + changeFlag := false + + if d.HasChange("description") { + request.Description = stringToPointer(d.Get("description").(string)) + changeFlag = true + + } + if d.HasChange("meta_data") { + request.SAMLMetadataDocument = stringToPointer(d.Get("meta_data").(string)) + changeFlag = true + } + + if changeFlag { + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + response, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdateSAMLProvider(request) + + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update CAM SAML provider description failed, reason:%s\n", logId, err.Error()) + return err + } + } + + return resourceTencentCloudCamSAMLProviderRead(d, meta) +} + +func resourceTencentCloudCamSAMLProviderDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_saml_provider.delete")() + + logId := getLogId(contextNil) + + SAMLProviderId := d.Id() + request := cam.NewDeleteSAMLProviderRequest() + request.Name = &SAMLProviderId + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + _, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DeleteSAMLProvider(request) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM SAML provider failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_saml_provider_test.go b/tencentcloud/resource_tc_cam_saml_provider_test.go new file mode 100644 index 0000000000..5d70ea4473 --- /dev/null +++ b/tencentcloud/resource_tc_cam_saml_provider_test.go @@ -0,0 +1,101 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamSAMLProvider_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamSAMLProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamSAMLProvider_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamSAMLProviderExists("tencentcloud_cam_saml_provider.saml_provider_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_saml_provider.saml_provider_basic", "name", "cam-saml-provider-test"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_saml_provider.saml_provider_basic", "meta_data"), + resource.TestCheckResourceAttr("tencentcloud_cam_saml_provider.saml_provider_basic", "description", "test"), + ), + }, { + Config: testAccCamSAMLProvider_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamSAMLProviderExists("tencentcloud_cam_saml_provider.saml_provider_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_saml_provider.saml_provider_basic", "name", "cam-SAML-provider-test"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_saml_provider.saml_provider_basic", "meta_data"), resource.TestCheckResourceAttr("tencentcloud_cam_saml_provider.saml_provider_basic", "description", "test2"), + ), + }, + { + ResourceName: "tencentcloud_cam_saml_provider.saml_provider_basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"provider_arn"}, + }, + }, + }) +} + +func testAccCheckCamSAMLProviderDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_saml_provider" { + continue + } + + _, err := camService.DescribeSAMLProviderById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("cam SAML provider still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamSAMLProviderExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("cam SAML provider %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("cam SAML provider id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeSAMLProviderById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamSAMLProvider_basic = ` +resource "tencentcloud_cam_saml_provider" "saml_provider_basic" { + name = "cam-saml-provider-test" + meta_data = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48bWQ6RW50aXR5RGVzY3JpcHRvciBlbnRpdHlJRD0iaHR0cDovL3d3dy5va3RhLmNvbS9leGsxa3F4bWNqUW1HQURNeTM1NyIgeG1sbnM6bWQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSI+PG1kOklEUFNTT0Rlc2NyaXB0b3IgV2FudEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48bWQ6S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEb0RDQ0FvaWdBd0lCQWdJR0FXM0lTcExvTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdRTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHDQpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVDQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0dsa2VIVmxkblJoTVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwDQpibVp2UUc5cmRHRXVZMjl0TUI0WERURTVNVEF4TkRBek1qSXhNMW9YRFRJNU1UQXhOREF6TWpNeE0xb3dnWkF4Q3pBSkJnTlZCQVlUDQpBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFLDQpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJYVdSNGRXVjJkR0V4SERBYUJna3Foa2lHDQo5dzBCQ1FFV0RXbHVabTlBYjJ0MFlTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2g4b3dqDQpZK2dQSUM3blQvNTduLzdmeXJzcDlHMXdxa2UxdXhjMHVrTndnQXozOVNpelY3QVhLMWRReTFLaThXWjJJMzFEczJkT0FNQ1FKR2pWDQpUWWNNbnA3KzhqUzNLdmxNUkRJamk5cmxuUi9vcnBvMll1RHVWby9jVzdidlRIS2h2REo1QWZRaWxzYlNPTXdUOWM2TVlYZGhBNVBwDQpzelFsK1UrdHJmcXUrdUorSER4SVQxdlhWaVI5YlY2SUFRSzZpbWZoc2wxWmVSUytjbVFVNEpjQWlYT0xtTnFVVWM2UkpxUzhrMW1mDQpBLzhmb2VyMGc3SG4xZDVXclpCc2gyUlR2Vzh1ZVdadHQ3dmh4QTlGdE5kSVlEcXJ0eElmMlZXcXhrSHM3WFZDSm5wTnJITVovT1BRDQpGY21YSGVxNlJJMlB3Q1RlOW8zZHZpM0hqeXBaOEl4dkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFHaHk1bG9nbGtTDQoyVHg2YS90MnF5VEx0YVV5cEwrNGhySGJoMVAweVVMc0NrSnFsM2wrWG9VZDZCY2FJaFNSVGFPQk95ODViL0UzelJ4K3JzQXJwTjVVDQp5ZThuUEM4a05PYW5vTk9wWnZvYmhpTzFlMFIvYmxEcnRBL0o5UlBwMWtmdlhmS2NSTTU3TlRCWXppTURlbnFQUTRFOWN1U2lGdFFxDQpJYmpIbThaM1B1YXgwRitldkZ3U1pJMDNCWXNISGw1d1EraEJBS3hTdTJINEZRdU93Zmpnb2EveEN6Z1NKYjJ2UXdEc1MxMk9mSkNiDQpSRm1ZL1VYZXQramFhdEVORktLZStZSUJpU0J2WG1adTN0MHN5NDZTNzlPVzBacXJ0NUh2bElsT2lpTFpaN1FZamxjM1kxeG1LZ1luDQpXM2M2WGZkdmhGWHo0ZDdkbWYvTUdpNGY0enM9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9tZDpLZXlEZXNjcmlwdG9yPjxtZDpOYW1lSURGb3JtYXQ+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQ8L21kOk5hbWVJREZvcm1hdD48bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzczwvbWQ6TmFtZUlERm9ybWF0PjxtZDpTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkeHVldnRhLm9rdGEuY29tL2FwcC9pZHh1ZW9yZzYzNzM1OF90ZXN0XzEvZXhrMWtxeG1jalFtR0FETXkzNTcvc3NvL3NhbWwiLz48bWQ6U2luZ2xlU2lnbk9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWR4dWV2dGEub2t0YS5jb20vYXBwL2lkeHVlb3JnNjM3MzU4X3Rlc3RfMS9leGsxa3F4bWNqUW1HQURNeTM1Ny9zc28vc2FtbCIvPjwvbWQ6SURQU1NPRGVzY3JpcHRvcj48L21kOkVudGl0eURlc2NyaXB0b3I+" + description = "test" +} +` + +const testAccCamSAMLProvider_update = ` +resource "tencentcloud_cam_saml_provider" "saml_provider_basic" { + name = "cam-SAML-provider-test" + meta_data = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48bWQ6RW50aXR5RGVzY3JpcHRvciBlbnRpdHlJRD0iaHR0cDovL3d3dy5va3RhLmNvbS9leGsxa3F4bWNqUW1HQURNeTM1NyIgeG1sbnM6bWQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSI+PG1kOklEUFNTT0Rlc2NyaXB0b3IgV2FudEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48bWQ6S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEb0RDQ0FvaWdBd0lCQWdJR0FXM0lTcExvTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdRTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHDQpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVDQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0dsa2VIVmxkblJoTVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwDQpibVp2UUc5cmRHRXVZMjl0TUI0WERURTVNVEF4TkRBek1qSXhNMW9YRFRJNU1UQXhOREF6TWpNeE0xb3dnWkF4Q3pBSkJnTlZCQVlUDQpBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFLDQpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJYVdSNGRXVjJkR0V4SERBYUJna3Foa2lHDQo5dzBCQ1FFV0RXbHVabTlBYjJ0MFlTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2g4b3dqDQpZK2dQSUM3blQvNTduLzdmeXJzcDlHMXdxa2UxdXhjMHVrTndnQXozOVNpelY3QVhLMWRReTFLaThXWjJJMzFEczJkT0FNQ1FKR2pWDQpUWWNNbnA3KzhqUzNLdmxNUkRJamk5cmxuUi9vcnBvMll1RHVWby9jVzdidlRIS2h2REo1QWZRaWxzYlNPTXdUOWM2TVlYZGhBNVBwDQpzelFsK1UrdHJmcXUrdUorSER4SVQxdlhWaVI5YlY2SUFRSzZpbWZoc2wxWmVSUytjbVFVNEpjQWlYT0xtTnFVVWM2UkpxUzhrMW1mDQpBLzhmb2VyMGc3SG4xZDVXclpCc2gyUlR2Vzh1ZVdadHQ3dmh4QTlGdE5kSVlEcXJ0eElmMlZXcXhrSHM3WFZDSm5wTnJITVovT1BRDQpGY21YSGVxNlJJMlB3Q1RlOW8zZHZpM0hqeXBaOEl4dkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFHaHk1bG9nbGtTDQoyVHg2YS90MnF5VEx0YVV5cEwrNGhySGJoMVAweVVMc0NrSnFsM2wrWG9VZDZCY2FJaFNSVGFPQk95ODViL0UzelJ4K3JzQXJwTjVVDQp5ZThuUEM4a05PYW5vTk9wWnZvYmhpTzFlMFIvYmxEcnRBL0o5UlBwMWtmdlhmS2NSTTU3TlRCWXppTURlbnFQUTRFOWN1U2lGdFFxDQpJYmpIbThaM1B1YXgwRitldkZ3U1pJMDNCWXNISGw1d1EraEJBS3hTdTJINEZRdU93Zmpnb2EveEN6Z1NKYjJ2UXdEc1MxMk9mSkNiDQpSRm1ZL1VYZXQramFhdEVORktLZStZSUJpU0J2WG1adTN0MHN5NDZTNzlPVzBacXJ0NUh2bElsT2lpTFpaN1FZamxjM1kxeG1LZ1luDQpXM2M2WGZkdmhGWHo0ZDdkbWYvTUdpNGY0enM9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9tZDpLZXlEZXNjcmlwdG9yPjxtZDpOYW1lSURGb3JtYXQ+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQ8L21kOk5hbWVJREZvcm1hdD48bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzczwvbWQ6TmFtZUlERm9ybWF0PjxtZDpTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkeHVldnRhLm9rdGEuY29tL2FwcC9pZHh1ZW9yZzYzNzM1OF90ZXN0XzEvZXhrMWtxeG1jalFtR0FETXkzNTcvc3NvL3NhbWwiLz48bWQ6U2luZ2xlU2lnbk9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWR4dWV2dGEub2t0YS5jb20vYXBwL2lkeHVlb3JnNjM3MzU4X3Rlc3RfMS9leGsxa3F4bWNqUW1HQURNeTM1Ny9zc28vc2FtbCIvPjwvbWQ6SURQU1NPRGVzY3JpcHRvcj48L21kOkVudGl0eURlc2NyaXB0b3I+" + description = "test2" +} +` diff --git a/tencentcloud/resource_tc_cam_user.go b/tencentcloud/resource_tc_cam_user.go new file mode 100644 index 0000000000..0dcb1d9c0e --- /dev/null +++ b/tencentcloud/resource_tc_cam_user.go @@ -0,0 +1,341 @@ +/* +Provides a resource to create a CAM user. + +Example Usage + +```hcl +resource "tencentcloud_cam_user" "foo" { + name = "cam-user-test" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" +} +``` + +Import + +CAM user can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_user.foo cam-user-test +``` +*/ +package tencentcloud + +import ( + "context" + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamUser() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamUserCreate, + Read: resourceTencentCloudCamUserRead, + Update: resourceTencentCloudCamUserUpdate, + Delete: resourceTencentCloudCamUserDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + ForceNew: true, + Required: true, + Description: "Name of CAM user.", + }, + "remark": { + Type: schema.TypeString, + Optional: true, + Default: "", + Description: "Remark of the CAM user.", + }, + "use_api": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Indicate whether to generate a secret key or not.", + }, + "console_login": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "Indicade whether the CAM user can login or not.", + }, + "password": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Sensitive: true, + ValidateFunc: validateAsConfigPassword, + Description: "The password of the CAM user. The password should be set with 8 characters or more and contains uppercase small letters, numbers, and special characters. Only valid when console_login set true. If not set and the value of console_login is true, a random password is automatically generated.", + }, + "need_reset_password": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Indicate whether the CAM user will reset the password the next time he/her logs in.", + }, + "phone_num": { + Type: schema.TypeString, + Optional: true, + Description: "Phone num of the CAM user.", + }, + "country_code": { + Type: schema.TypeString, + Optional: true, + Description: "Country code of the phone num, like '86'.", + }, + "email": { + Type: schema.TypeString, + Optional: true, + Description: "Email of the CAM user.", + }, + "uin": { + Type: schema.TypeInt, + Computed: true, + Description: "Uin of the CAM User.", + }, + "secret_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + Description: "Secret key of the CAM user.", + }, + "secret_id": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + Description: "Secret Id of the CAM user.", + }, + "uid": { + Type: schema.TypeInt, + Computed: true, + Description: "Id of the CAM user.", + }, + }, + } +} + +func resourceTencentCloudCamUserCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user.create")() + + logId := getLogId(contextNil) + request := cam.NewAddUserRequest() + request.Name = stringToPointer(d.Get("name").(string)) + //optional + if v, ok := d.GetOk("remark"); ok { + request.Remark = stringToPointer(v.(string)) + } + if v, ok := d.GetOkExists("use_api"); ok { + apiBool := v.(bool) + apiInt := uint64(1) + if !apiBool { + apiInt = uint64(0) + } + request.UseApi = &apiInt + } + if v, ok := d.GetOkExists("console_login"); ok { + loginBool := v.(bool) + loginInt := uint64(1) + if !loginBool { + loginInt = uint64(0) + } + request.ConsoleLogin = &loginInt + } + if v, ok := d.GetOkExists("need_reset_password"); ok { + resetBool := v.(bool) + resetInt := uint64(1) + if !resetBool { + resetInt = uint64(0) + } + request.NeedResetPassword = &resetInt + } + if v, ok := d.GetOk("phone_num"); ok { + request.PhoneNum = stringToPointer(v.(string)) + } + if v, ok := d.GetOk("country_code"); ok { + request.CountryCode = stringToPointer(v.(string)) + } + + if v, ok := d.GetOk("email"); ok { + request.Email = stringToPointer(v.(string)) + } + if v, ok := d.GetOk("password"); ok { + request.Password = stringToPointer(v.(string)) + } + + var response *cam.AddUserResponse + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + result, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().AddUser(request) + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create user failed, reason:%s\n", logId, err.Error()) + return err + } + if response.Response.Uid == nil { + return fmt.Errorf("CAM user id is nil") + } + + d.SetId(*response.Response.Name) + d.Set("secret_key", *response.Response.SecretKey) + d.Set("password", *response.Response.Password) + d.Set("secret_id", *response.Response.SecretId) + return resourceTencentCloudCamUserRead(d, meta) +} + +func resourceTencentCloudCamUserRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + userId := d.Id() + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var instance *cam.GetUserResponse + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeUserById(ctx, userId) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read CAM user failed, reason:%s\n", logId, err.Error()) + return err + } + + d.Set("name", userId) + d.Set("uin", int(*instance.Response.Uin)) + d.Set("uid", int(*instance.Response.Uid)) + d.Set("remark", *instance.Response.Remark) + d.Set("phone_num", *instance.Response.PhoneNum) + d.Set("country_code", *instance.Response.CountryCode) + d.Set("email", *instance.Response.Email) + if int(*instance.Response.ConsoleLogin) == 0 { + d.Set("console_login", false) + } else if int(*instance.Response.ConsoleLogin) == 1 { + d.Set("console_login", true) + } + + return nil +} + +func resourceTencentCloudCamUserUpdate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user.update")() + + logId := getLogId(contextNil) + + userId := d.Id() + + var updateAttrs []string + + request := cam.NewUpdateUserRequest() + request.Name = &userId + if d.HasChange("remark") { + request.Remark = stringToPointer(d.Get("remark").(string)) + updateAttrs = append(updateAttrs, "remark") + } + + if d.HasChange("console_login") { + consoleLogin := d.Get("console_login").(bool) + consoleLogin64 := uint64(0) + if consoleLogin { + consoleLogin64 = uint64(1) + } + request.ConsoleLogin = &consoleLogin64 + updateAttrs = append(updateAttrs, "console_login") + } + + if d.HasChange("need_reset_password") { + resetBool := d.Get("need_reset_password").(bool) + resetBool64 := uint64(0) + if resetBool { + resetBool64 = uint64(1) + } + request.NeedResetPassword = &resetBool64 + updateAttrs = append(updateAttrs, "need_reset_password") + } + + if d.HasChange("phone_num") { + request.PhoneNum = stringToPointer(d.Get("phone_num").(string)) + updateAttrs = append(updateAttrs, "phone_num") + } + if d.HasChange("country_code") { + request.CountryCode = stringToPointer(d.Get("country_code").(string)) + updateAttrs = append(updateAttrs, "country_code") + } + if d.HasChange("email") { + request.Email = stringToPointer(d.Get("email").(string)) + updateAttrs = append(updateAttrs, "email") + } + + if len(updateAttrs) > 0 { + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + response, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().UpdateUser(request) + + if e != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), e.Error()) + return retryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update CAM user description failed, reason:%s\n", logId, err.Error()) + return err + } + } + + return nil +} + +func resourceTencentCloudCamUserDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user.delete")() + + logId := getLogId(contextNil) + + userId := d.Id() + request := cam.NewDeleteUserRequest() + request.Name = &userId + + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + _, e := meta.(*TencentCloudClient).apiV3Conn.UseCamClient().DeleteUser(request) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete CAM user failed, reason:%s\n", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_user_policy_attachment.go b/tencentcloud/resource_tc_cam_user_policy_attachment.go new file mode 100644 index 0000000000..ce232f6672 --- /dev/null +++ b/tencentcloud/resource_tc_cam_user_policy_attachment.go @@ -0,0 +1,171 @@ +/* +Provides a resource to create a CAM user policy attachment. + +Example Usage + +```hcl +resource "tencentcloud_cam_user_policy_attachment" "foo" { + user_id = "cam-test" + policy_id = "26800353" +} +``` + +Import + +CAM user policy attachment can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_user_attachment.foo cam-test#26800353 +``` +*/ +package tencentcloud + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" +) + +func resourceTencentCloudCamUserPolicyAttachment() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudCamUserPolicyAttachmentCreate, + Read: resourceTencentCloudCamUserPolicyAttachmentRead, + Delete: resourceTencentCloudCamUserPolicyAttachmentDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the attached cam user.", + }, + "policy_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Id of the policy.", + }, + "create_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways.", + }, + "policy_type": { + Type: schema.TypeString, + Computed: true, + Description: "Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy.", + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time of the CAM user policy attachment.", + }, + "policy_name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the policy.", + }, + }, + } +} + +func resourceTencentCloudCamUserPolicyAttachmentCreate(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user_policy_attachment.create")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + userId := d.Get("user_id").(string) + policyId := d.Get("policy_id").(string) + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + e := camService.AddUserPolicyAttachment(ctx, userId, policyId) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete cam user policy attachment failed, reason:%s\n ", logId, err.Error()) + return err + } + + d.SetId(userId + "#" + policyId) + + return resourceTencentCloudCamUserPolicyAttachmentRead(d, meta) +} + +func resourceTencentCloudCamUserPolicyAttachmentRead(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user_policy_attachment.read")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + userPolicyAttachmentId := d.Id() + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + var instance *cam.AttachPolicyInfo + err := resource.Retry(readRetryTimeout, func() *resource.RetryError { + result, e := camService.DescribeUserPolicyAttachmentById(ctx, userPolicyAttachmentId) + if e != nil { + return retryError(e) + } + instance = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s read cam user policy attachment failed, reason:%s\n ", logId, err.Error()) + return err + } + //split id + userId, policyId, e := camService.decodeCamPolicyAttachmentId(userPolicyAttachmentId) + if e != nil { + return e + } + d.Set("user_id", userId) + d.Set("policy_id", strconv.Itoa(int(policyId))) + d.Set("policy_name", *instance.PolicyName) + d.Set("create_time", *instance.AddTime) + d.Set("create_mode", int(*instance.CreateMode)) + d.Set("policy_type", *instance.PolicyType) + return nil +} + +func resourceTencentCloudCamUserPolicyAttachmentDelete(d *schema.ResourceData, meta interface{}) error { + defer logElapsed("resource.tencentcloud_cam_user_policy_attachment.delete")() + + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + userPolicyAttachmentId := d.Id() + + camService := CamService{ + client: meta.(*TencentCloudClient).apiV3Conn, + } + err := resource.Retry(writeRetryTimeout, func() *resource.RetryError { + e := camService.DeleteUserPolicyAttachmentById(ctx, userPolicyAttachmentId) + if e != nil { + log.Printf("[CRITAL]%s reason[%s]\n", logId, e.Error()) + return retryError(e) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete cam user policy attachment failed, reason:%s\n ", logId, err.Error()) + return err + } + + return nil +} diff --git a/tencentcloud/resource_tc_cam_user_policy_attachment_test.go b/tencentcloud/resource_tc_cam_user_policy_attachment_test.go new file mode 100644 index 0000000000..762e61f693 --- /dev/null +++ b/tencentcloud/resource_tc_cam_user_policy_attachment_test.go @@ -0,0 +1,102 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamUserPolicyAttachment_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamUserPolicyAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamUserPolicyAttachment_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamUserPolicyAttachmentExists("tencentcloud_cam_user_policy_attachment.user_policy_attachment_basic"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user_policy_attachment.user_policy_attachment_basic", "user_id"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user_policy_attachment.user_policy_attachment_basic", "policy_id"), + ), + }, + { + ResourceName: "tencentcloud_cam_user_policy_attachment.user_policy_attachment_basic", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckCamUserPolicyAttachmentDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_user_policy_attachment" { + continue + } + + _, err := camService.DescribeUserPolicyAttachmentById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("cam user policy attachment still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamUserPolicyAttachmentExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("cam user policy attachment %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("cam user policy attachment id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeUserPolicyAttachmentById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +//need to add policy resource definition +const testAccCamUserPolicyAttachment_basic = ` +resource "tencentcloud_cam_user" "user" { + name = "cam-user-testt" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} + +resource "tencentcloud_cam_policy" "policy" { + name = "cam-policy-test3" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} + +resource "tencentcloud_cam_user_policy_attachment" "user_policy_attachment_basic" { + user_id = "${tencentcloud_cam_user.user.id}" + policy_id = "${tencentcloud_cam_policy.policy.id}" +} +` diff --git a/tencentcloud/resource_tc_cam_user_test.go b/tencentcloud/resource_tc_cam_user_test.go new file mode 100644 index 0000000000..481c4126d2 --- /dev/null +++ b/tencentcloud/resource_tc_cam_user_test.go @@ -0,0 +1,206 @@ +package tencentcloud + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccTencentCloudCamUser_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamUserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamUser_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamUserExists("tencentcloud_cam_user.user_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "name", "cam-user-test0"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "remark", "test"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "console_login", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "need_reset_password", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "use_api", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "phone_num", "13631555963"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "country_code", "86"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "password", "Gail@1234"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "email", "1234@qq.com"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "uin"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "uid"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "secret_key"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "secret_id"), + ), + }, { + Config: testAccCamUser_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamUserExists("tencentcloud_cam_user.user_basic"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "name", "cam-user-test0"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "remark", "test1235"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "console_login", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "need_reset_password", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "use_api", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "phone_num", "13670093505"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "country_code", "72"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "password", "Gail@12346"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_basic", "email", "141515@qq.com"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "uin"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "uid"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "secret_key"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_basic", "secret_id"), + ), + }, { + ResourceName: "tencentcloud_cam_user.user_basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"secret_key", "secret_id", "password", "need_reset_password", "use_api"}, + }, + }, + }) +} + +func TestAccTencentCloudCamUser_nilPassword(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamUserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamUser_nilPassword, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamUserExists("tencentcloud_cam_user.user_nil_password"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "name", "cam-user-testnil"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "remark", "test"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "console_login", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "need_reset_password", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "use_api", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "phone_num", "13631555963"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_nil_password", "country_code", "86"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_nil_password", "uin"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_nil_password", "uid"), + ), + }, + }, + }) +} + +func TestAccTencentCloudCamUser_withoutKey(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCamUserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCamUser_withoutKey, + Check: resource.ComposeTestCheckFunc( + testAccCheckCamUserExists("tencentcloud_cam_user.user_without_key"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "name", "cam-user-testkey"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "remark", "test"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "console_login", "false"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "need_reset_password", "true"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "use_api", "false"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "phone_num", "13631555963"), + resource.TestCheckResourceAttr("tencentcloud_cam_user.user_without_key", "country_code", "86"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_without_key", "uin"), + resource.TestCheckResourceAttrSet("tencentcloud_cam_user.user_without_key", "uid"), + ), + }, + }, + }) +} +func testAccCheckCamUserDestroy(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "tencentcloud_cam_user" { + continue + } + + _, err := camService.DescribeUserById(ctx, rs.Primary.ID) + if err == nil { + return fmt.Errorf("CAM user still exists: %s", rs.Primary.ID) + } + } + return nil +} + +func testAccCheckCamUserExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + logId := getLogId(contextNil) + ctx := context.WithValue(context.TODO(), "logId", logId) + + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("CAM user %s is not found", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("CAM user id is not set") + } + camService := CamService{ + client: testAccProvider.Meta().(*TencentCloudClient).apiV3Conn, + } + _, err := camService.DescribeUserById(ctx, rs.Primary.ID) + if err != nil { + return err + } + return nil + } +} + +const testAccCamUser_basic = ` +resource "tencentcloud_cam_user" "user_basic" { + name = "cam-user-test0" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" + email = "1234@qq.com" +} +` + +const testAccCamUser_update = ` +resource "tencentcloud_cam_user" "user_basic" { + name = "cam-user-test0" + remark = "test1235" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@12346" + phone_num = "13670093505" + country_code = "72" + email = "141515@qq.com" +} +` +const testAccCamUser_nilPassword = ` +resource "tencentcloud_cam_user" "user_nil_password" { + name = "cam-user-testnil" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + phone_num = "13631555963" + country_code = "86" + email = "141515@qq.com" +} +` +const testAccCamUser_withoutKey = ` +resource "tencentcloud_cam_user" "user_without_key" { + name = "cam-user-testkey" + remark = "test" + console_login = false + use_api = false + need_reset_password = true + phone_num = "13631555963" + country_code = "86" + email = "141515@qq.com" +} +` diff --git a/tencentcloud/service_tencentcloud_cam.go b/tencentcloud/service_tencentcloud_cam.go new file mode 100644 index 0000000000..037a1ff9e2 --- /dev/null +++ b/tencentcloud/service_tencentcloud_cam.go @@ -0,0 +1,1044 @@ +package tencentcloud + +import ( + "context" + "encoding/json" + "fmt" + "log" + "reflect" + "strconv" + "strings" + + cam "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116" + "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/connectivity" + "github.com/terraform-providers/terraform-provider-tencentcloud/tencentcloud/ratelimit" +) + +type CamService struct { + client *connectivity.TencentCloudClient +} + +func (me *CamService) DescribeRoleById(ctx context.Context, roleId string) (camInstance *cam.RoleInfo, errRet error) { + logId := getLogId(ctx) + request := cam.NewDescribeRoleListRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) //to save in extension + result := make([]*cam.RoleInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().DescribeRoleList(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + for _, role := range response.Response.List { + if *role.RoleId == roleId { + result = append(result, role) + } + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + + if len(result) == 0 { + return nil, fmt.Errorf("CAM role id is not found") + } + camInstance = result[0] + return +} + +func (me *CamService) DescribeRolesByFilter(ctx context.Context, params map[string]interface{}) (roles []*cam.RoleInfo, errRet error) { + logId := getLogId(ctx) + //need travel + request := cam.NewDescribeRoleListRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + roles = make([]*cam.RoleInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().DescribeRoleList(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + + for _, role := range response.Response.List { + if params["role_id"] != nil { + if *role.RoleId != params["role_id"] { + continue + } + } + if params["name"] != nil { + if *role.RoleName != params["name"] { + continue + } + } + if params["description"] != nil { + if *role.Description != params["description"] { + continue + } + } + roles = append(roles, role) + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) DeleteRoleById(ctx context.Context, roleId string) error { + + logId := getLogId(ctx) + request := cam.NewDeleteRoleRequest() + request.RoleId = &roleId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().DeleteRole(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + return nil +} + +func (me *CamService) decodeCamPolicyAttachmentId(id string) (instanceId string, policyId64 uint64, errRet error) { + items := strings.Split(id, "#") + if len(items) != 2 { + return instanceId, policyId64, fmt.Errorf(" id is not exist %s", id) + } + instanceId = items[0] + policyId, e := strconv.Atoi(items[1]) + if e != nil { + errRet = e + return + } + policyId64 = uint64(policyId) + return +} + +func (me *CamService) DescribeRolePolicyAttachmentById(ctx context.Context, rolePolicyAttachmentId string) (policyOfRole *cam.AttachedPolicyOfRole, errRet error) { + logId := getLogId(ctx) + roleId, policyId, e := me.decodeCamPolicyAttachmentId(rolePolicyAttachmentId) + if e != nil { + return nil, e + } + request := cam.NewListAttachedRolePoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + result := make([]*cam.AttachedPolicyOfRole, 0) + for { + request.Page = &pageStart + request.Rp = &rp + request.RoleId = &roleId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListAttachedRolePolicies(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + for _, policy := range response.Response.List { + if *policy.PolicyId == policyId { + result = append(result, policy) + } + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + + if len(result) == 0 { + return nil, fmt.Errorf("CAM role policy attachment id is not found") + } + policyOfRole = result[0] + return +} + +func (me *CamService) DescribeRolePolicyAttachmentsByFilter(ctx context.Context, params map[string]interface{}) (policyOfRoles []*cam.AttachedPolicyOfRole, errRet error) { + logId := getLogId(ctx) + roleId := params["role_id"].(string) + request := cam.NewListAttachedRolePoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + policyOfRoles = make([]*cam.AttachedPolicyOfRole, 0) + for { + request.Page = &pageStart + request.Rp = &rp + request.RoleId = &roleId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListAttachedRolePolicies(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + for _, policy := range response.Response.List { + if params["policy_id"] != nil { + if *policy.PolicyId != params["policy_id"] { + continue + } + } + if params["policy_type"] != nil { + if *policy.PolicyType != params["policy_type"] { + continue + } + } + if params["create_mode"] != nil { + if int(*policy.CreateMode) != params["create_mode"] { + continue + } + } + policyOfRoles = append(policyOfRoles, policy) + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) DeleteRolePolicyAttachmentById(ctx context.Context, rolePolicyAttachmentId string) error { + logId := getLogId(ctx) + roleId, policyId, e := me.decodeCamPolicyAttachmentId(rolePolicyAttachmentId) + if e != nil { + return e + } + request := cam.NewDetachRolePolicyRequest() + request.DetachRoleId = &roleId + request.PolicyId = &policyId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().DetachRolePolicy(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return nil +} + +func (me *CamService) DescribeUserPolicyAttachmentById(ctx context.Context, userPolicyAttachmentId string) (policyResults *cam.AttachPolicyInfo, errRet error) { + logId := getLogId(ctx) + + userId, policyId, e := me.decodeCamPolicyAttachmentId(userPolicyAttachmentId) + if e != nil { + return nil, e + } + user, err := me.DescribeUserById(ctx, userId) + if err != nil { + return nil, err + } + uin := user.Response.Uin + + request := cam.NewListAttachedUserPoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + result := make([]*cam.AttachPolicyInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + request.TargetUin = uin + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListAttachedUserPolicies(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + for _, policy := range response.Response.List { + if *policy.PolicyId == policyId { + result = append(result, policy) + } + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + + if len(result) == 0 { + return nil, fmt.Errorf("CAM user policy attachment id is not found") + } + policyResults = result[0] + return +} + +func (me *CamService) DescribeUserPolicyAttachmentsByFilter(ctx context.Context, params map[string]interface{}) (policyResults []*cam.AttachPolicyInfo, errRet error) { + logId := getLogId(ctx) + userId := params["user_id"].(string) + user, err := me.DescribeUserById(ctx, userId) + if err != nil { + return nil, err + } + uin := user.Response.Uin + request := cam.NewListAttachedUserPoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + policyResults = make([]*cam.AttachPolicyInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + request.TargetUin = uin + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListAttachedUserPolicies(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + for _, policy := range response.Response.List { + if params["policy_id"] != nil { + if *policy.PolicyId != params["policy_id"] { + continue + } + } + if params["policy_type"] != nil { + if *policy.PolicyType != params["policy_type"] { + continue + } + } + if params["create_mode"] != nil { + if int(*policy.CreateMode) != params["create_mode"] { + continue + } + } + policyResults = append(policyResults, policy) + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) AddUserPolicyAttachment(ctx context.Context, userId string, policyId string) error { + logId := getLogId(ctx) + + user, err := me.DescribeUserById(ctx, userId) + if err != nil { + return err + } + uin := user.Response.Uin + policyIdInt, e := strconv.Atoi(policyId) + if e != nil { + return e + } + policyIdInt64 := uint64(policyIdInt) + request := cam.NewAttachUserPolicyRequest() + request.AttachUin = uin + request.PolicyId = &policyIdInt64 + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().AttachUserPolicy(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return nil +} + +func (me *CamService) DeleteUserPolicyAttachmentById(ctx context.Context, userPolicyAttachmentId string) error { + logId := getLogId(ctx) + userId, policyId, e := me.decodeCamPolicyAttachmentId(userPolicyAttachmentId) + if e != nil { + return e + } + user, err := me.DescribeUserById(ctx, userId) + if err != nil { + return err + } + uin := user.Response.Uin + + request := cam.NewDetachUserPolicyRequest() + request.DetachUin = uin + request.PolicyId = &policyId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().DetachUserPolicy(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return nil +} + +func (me *CamService) DescribeGroupPolicyAttachmentById(ctx context.Context, groupPolicyAttachmentId string) (policyResults *cam.AttachPolicyInfo, errRet error) { + logId := getLogId(ctx) + groupId, policyId, e := me.decodeCamPolicyAttachmentId(groupPolicyAttachmentId) + if e != nil { + errRet = e + return + } + groupIdInt, ee := strconv.Atoi(groupId) + if ee != nil { + errRet = ee + return + } + groupIdInt64 := uint64(groupIdInt) + request := cam.NewListAttachedGroupPoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + result := make([]*cam.AttachPolicyInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + request.TargetGroupId = &groupIdInt64 + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListAttachedGroupPolicies(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + for _, policy := range response.Response.List { + if *policy.PolicyId == policyId { + result = append(result, policy) + } + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + if len(result) == 0 { + return nil, fmt.Errorf("CAM group policy attachment id is not found") + } + policyResults = result[0] + return +} + +func (me *CamService) DescribeGroupPolicyAttachmentsByFilter(ctx context.Context, params map[string]interface{}) (policyResults []*cam.AttachPolicyInfo, errRet error) { + logId := getLogId(ctx) + groupId := params["group_id"].(string) + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + errRet = e + return + } + groupIdInt64 := uint64(groupIdInt) + request := cam.NewListAttachedGroupPoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + policyResults = make([]*cam.AttachPolicyInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + request.TargetGroupId = &groupIdInt64 + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListAttachedGroupPolicies(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.List) < 1 { + break + } + + for _, policy := range response.Response.List { + if params["policy_id"] != nil { + if *policy.PolicyId != params["policy_id"] { + continue + } + } + if params["policy_type"] != nil { + if *policy.PolicyType != params["policy_type"] { + continue + } + } + if params["create_mode"] != nil { + if int(*policy.CreateMode) != params["create_mode"] { + continue + } + } + policyResults = append(policyResults, policy) + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) AddGroupPolicyAttachment(ctx context.Context, groupId string, policyId string) error { + logId := getLogId(ctx) + + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + return e + } + groupIdInt64 := uint64(groupIdInt) + policyIdInt, ee := strconv.Atoi(policyId) + if ee != nil { + return ee + } + policyIdInt64 := uint64(policyIdInt) + + request := cam.NewAttachGroupPolicyRequest() + request.AttachGroupId = &groupIdInt64 + request.PolicyId = &policyIdInt64 + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().AttachGroupPolicy(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return nil +} + +func (me *CamService) DeleteGroupPolicyAttachmentById(ctx context.Context, groupPolicyAttachmentId string) error { + logId := getLogId(ctx) + groupId, policyId, e := me.decodeCamPolicyAttachmentId(groupPolicyAttachmentId) + if e != nil { + return e + } + groupIdInt, ee := strconv.Atoi(groupId) + if ee != nil { + return ee + } + groupIdInt64 := uint64(groupIdInt) + + request := cam.NewDetachGroupPolicyRequest() + request.DetachGroupId = &groupIdInt64 + request.PolicyId = &policyId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().DetachGroupPolicy(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + return err + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return nil +} + +func (me *CamService) DescribePolicyById(ctx context.Context, policyId string) (result *cam.GetPolicyResponse, errRet error) { + logId := getLogId(ctx) + request := cam.NewGetPolicyRequest() + policyIdInt, e := strconv.Atoi(policyId) + if e != nil { + errRet = e + return + } + policyIdInt64 := uint64(policyIdInt) + request.PolicyId = &policyIdInt64 + result, err := me.client.UseCamClient().GetPolicy(request) + + if err != nil { + log.Printf("[CRITAL]%s read CAM role failed, reason:%s\n", logId, err.Error()) + return nil, err + } else { + if result == nil { + return nil, fmt.Errorf("policy id not found") + } + if result.Response == nil { + return nil, fmt.Errorf("policy id not found") + } + if result.Response.PolicyName == nil { + return nil, fmt.Errorf("policy id not found") + } + } + + return +} + +func (me *CamService) DescribePoliciesByFilter(ctx context.Context, params map[string]interface{}) (policies []*cam.StrategyInfo, errRet error) { + logId := getLogId(ctx) + policyId := -1 + policyName := "" + //notice this policy type is different from the policy attachment, this sdk returns int while the attachments returns string + policyType := -1 + description := "" + createMode := -1 + + request := cam.NewListPoliciesRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + + for k, v := range params { + if k == "policy_id" { + policyId = v.(int) + } + if k == "name" { + policyName = v.(string) + } + if k == "type" { + policyType = v.(int) + } + if k == "description" { + description = v.(string) + } + if k == "create_mode" { + createMode = v.(int) + } + } + policies = make([]*cam.StrategyInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListPolicies(request) + if err != nil { + log.Printf("[CRITAL]%s read CAM role failed, reason:%s\n", logId, err.Error()) + errRet = err + return + } + for _, policy := range response.Response.List { + if policyId != -1 { + if int(*policy.PolicyId) != policyId { + continue + } + } + if policyName != "" { + if *policy.PolicyName != policyName { + continue + } + } + if policyType != -1 { + if int(*policy.Type) != policyType { + continue + } + } + if description != "" { + if *policy.Description != description { + continue + } + } + if createMode != -1 { + if int(*policy.CreateMode) != createMode { + continue + } + } + policies = append(policies, policy) + } + if len(response.Response.List) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) DescribeUserById(ctx context.Context, userId string) (response *cam.GetUserResponse, errRet error) { + logId := getLogId(ctx) + request := cam.NewGetUserRequest() + request.Name = &userId + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().GetUser(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return +} + +func (me *CamService) DescribeUsersByFilter(ctx context.Context, params map[string]interface{}) (result []*cam.SubAccountInfo, errRet error) { + logId := getLogId(ctx) + request := cam.NewListUsersRequest() + + result = make([]*cam.SubAccountInfo, 0) + + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListUsers(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + for _, user := range response.Response.Data { + if params["name"] != nil { + if params["name"].(string) != *user.Name { + continue + } + } + if params["remark"] != nil { + if user.Remark != nil { + if params["remark"].(string) != *user.Remark { + continue + } + } else { + continue + } + } + if params["phone_num"] != nil { + if user.PhoneNum != nil { + if params["phone_num"].(string) != *user.PhoneNum { + continue + } + } else { + continue + } + } + if params["country_code"] != nil { + if user.PhoneNum != nil { + if params["country_code"].(string) != *user.PhoneNum { + continue + } + } else { + continue + } + } + if params["email"] != nil { + if user.PhoneNum != nil { + if params["email"].(string) != *user.PhoneNum { + continue + } + } else { + continue + } + } + if params["uin"] != nil { + if user.Uin != nil { + if params["uin"].(int) != int(*user.Uin) { + continue + } + } else { + continue + } + } + if params["uid"] != nil { + if user.Uid != nil { + if params["uid"].(int) != int(*user.Uid) { + continue + } + } else { + continue + } + } + if params["console_login"] != nil { + if user.ConsoleLogin != nil { + if params["console_login"].(int) != int(*user.ConsoleLogin) { + continue + } + } else { + continue + } + } + result = append(result, user) + } + + return +} + +func (me *CamService) DescribeGroupById(ctx context.Context, groupId string) (camInstance *cam.GetGroupResponse, errRet error) { + logId := getLogId(ctx) + request := cam.NewGetGroupRequest() + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + errRet = e + return + } + groupIdInt64 := uint64(groupIdInt) + request.GroupId = &groupIdInt64 + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().GetGroup(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + return +} + +func (me *CamService) DescribeGroupsByFilter(ctx context.Context, params map[string]interface{}) (groups []*cam.GroupInfo, errRet error) { + logId := getLogId(ctx) + request := cam.NewListGroupsRequest() + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + groups = make([]*cam.GroupInfo, 0) + for { + request.Page = &pageStart + request.Rp = &rp + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListGroups(request) + if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if response == nil || len(response.Response.GroupInfo) < 1 { + break + } + for _, group := range response.Response.GroupInfo { + if params["group_id"] != nil { + if int(*group.GroupId) != params["group_id"].(int) { + continue + } + } + if params["name"] != nil { + if *group.GroupName != params["name"].(string) { + continue + } + } + if params["remark"] != nil { + if group.Remark != nil && *group.Remark != params["remark"].(string) { + continue + } + } + groups = append(groups, group) + } + if len(response.Response.GroupInfo) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) DescribeGroupMembershipById(ctx context.Context, groupId string) (members []*string, errRet error) { + logId := getLogId(ctx) + groupIdInt, e := strconv.Atoi(groupId) + if e != nil { + errRet = e + return + } + groupIdInt64 := uint64(groupIdInt) + pageStart := uint64(1) + rp := uint64(PAGE_ITEM) + members = make([]*string, 0) + request := cam.NewListUsersForGroupRequest() + request.GroupId = &groupIdInt64 + for { + request.Page = &pageStart + request.Rp = &rp + response, err := me.client.UseCamClient().ListUsersForGroup(request) + if err != nil { + log.Printf("[CRITAL]%s read CAM group membership failed, reason:%s\n", logId, err.Error()) + errRet = err + return + } + + if response == nil || len(response.Response.UserInfo) < 1 { + break + } + for _, member := range response.Response.UserInfo { + + members = append(members, member.Name) + } + if len(response.Response.UserInfo) < PAGE_ITEM { + break + } + pageStart += 1 + } + return +} + +func (me *CamService) DescribeSAMLProviderById(ctx context.Context, providerName string) (result *cam.GetSAMLProviderResponse, errRet error) { + logId := getLogId(ctx) + request := cam.NewGetSAMLProviderRequest() + request.Name = &providerName + result, err := me.client.UseCamClient().GetSAMLProvider(request) + + if err != nil { + log.Printf("[CRITAL]%s read cam SAML provider failed, reason:%s\n", logId, err.Error()) + return nil, err + } else { + if result == nil { + return nil, fmt.Errorf("SAML provider name not found") + } + if result.Response == nil { + return nil, fmt.Errorf("SAML provider name not found") + } + if result.Response == nil || result.Response.Name == nil { + return nil, fmt.Errorf("SAML provider name not found") + } + } + + return +} + +func (me *CamService) DescribeSAMLProvidersByFilter(ctx context.Context, params map[string]interface{}) (providers []*cam.SAMLProviderInfo, errRet error) { + logId := getLogId(ctx) + name := "" + description := "" + + request := cam.NewListSAMLProvidersRequest() + + for k, v := range params { + if k == "name" { + name = v.(string) + } + if k == "description" { + description = v.(string) + } + } + providers = make([]*cam.SAMLProviderInfo, 0) + ratelimit.Check(request.GetAction()) + response, err := me.client.UseCamClient().ListSAMLProviders(request) + if err != nil { + log.Printf("[CRITAL]%s read cam SAML provider failed, reason:%s\n", logId, err.Error()) + errRet = err + return + } + for _, provider := range response.Response.SAMLProviderSet { + if name != "" { + if *provider.Name != name { + continue + } + } + if description != "" { + if *provider.Description != description { + continue + } + } + providers = append(providers, provider) + } + + return +} + +func (me *CamService) PolicyDocumentForceCheck(document string) error { + + //Policy syntax allows multi formats, but returns with only one format. In this case, the user's input may be different from the output value. To avoid this, terraform must make sure the syntax of the input policy document consists with the syntax of final returned output + type Principal struct { + Qcs []string `json:"qcs"` + } + type Statement struct { + Resource interface{} `json:"resource"` + //to avoid json unmarshal eats up with '/' + Action []json.RawMessage `json:"action"` + Principal Principal `json:"principal"` + } + type Document struct { + Version string `json:"version"` + Statement []Statement `json:"statement"` + } + var documentJson Document + err := json.Unmarshal([]byte(document), &documentJson) + if err != nil { + return err + } + for _, state := range documentJson.Statement { + //multi value case in elemant `resource`, `action`: input:""/[""], output: [""] + if state.Resource != nil { + if reflect.TypeOf(state.Resource) == reflect.TypeOf("string") { + return fmt.Errorf("The format of `resource` in policy document is invalid, its type must be array") + } + } + + if state.Action != nil { + if reflect.TypeOf(state.Action) == reflect.TypeOf("string") { + return fmt.Errorf("The format of `resource` in policy document is invalid, its type must be array") + } + + } + //multi value case in elemant `principal.qcs`:input :root/[uin of the user], output:[uin of the user] + for _, qcs := range state.Principal.Qcs { + if strings.Contains(qcs, "root") { + return fmt.Errorf("`root` format is not supported, please replace it with uin") + } + } + } + return nil +} + +func diffJson(old string, new string) (flag bool, errRet error) { + var oldJson interface{} + err := json.Unmarshal([]byte(old), &oldJson) + if err != nil { + errRet = err + return + } + var newJson interface{} + err = json.Unmarshal([]byte(new), &newJson) + if err != nil { + errRet = err + return + } + flag = reflect.DeepEqual(oldJson, newJson) + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116/client.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116/client.go new file mode 100644 index 0000000000..b88d0e6b33 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116/client.go @@ -0,0 +1,1119 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v20190116 + +import ( + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" +) + +const APIVersion = "2019-01-16" + +type Client struct { + common.Client +} + +// Deprecated +func NewClientWithSecretId(secretId, secretKey, region string) (client *Client, err error) { + cpf := profile.NewClientProfile() + client = &Client{} + client.Init(region).WithSecretId(secretId, secretKey).WithProfile(cpf) + return +} + +func NewClient(credential *common.Credential, region string, clientProfile *profile.ClientProfile) (client *Client, err error) { + client = &Client{} + client.Init(region). + WithCredential(credential). + WithProfile(clientProfile) + return +} + + +func NewAddUserRequest() (request *AddUserRequest) { + request = &AddUserRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "AddUser") + return +} + +func NewAddUserResponse() (response *AddUserResponse) { + response = &AddUserResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 添加子用户 +func (c *Client) AddUser(request *AddUserRequest) (response *AddUserResponse, err error) { + if request == nil { + request = NewAddUserRequest() + } + response = NewAddUserResponse() + err = c.Send(request, response) + return +} + +func NewAddUserToGroupRequest() (request *AddUserToGroupRequest) { + request = &AddUserToGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "AddUserToGroup") + return +} + +func NewAddUserToGroupResponse() (response *AddUserToGroupResponse) { + response = &AddUserToGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 用户加入到用户组 +func (c *Client) AddUserToGroup(request *AddUserToGroupRequest) (response *AddUserToGroupResponse, err error) { + if request == nil { + request = NewAddUserToGroupRequest() + } + response = NewAddUserToGroupResponse() + err = c.Send(request, response) + return +} + +func NewAttachGroupPolicyRequest() (request *AttachGroupPolicyRequest) { + request = &AttachGroupPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "AttachGroupPolicy") + return +} + +func NewAttachGroupPolicyResponse() (response *AttachGroupPolicyResponse) { + response = &AttachGroupPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AttachGroupPolicy)可用于绑定策略到用户组。 +func (c *Client) AttachGroupPolicy(request *AttachGroupPolicyRequest) (response *AttachGroupPolicyResponse, err error) { + if request == nil { + request = NewAttachGroupPolicyRequest() + } + response = NewAttachGroupPolicyResponse() + err = c.Send(request, response) + return +} + +func NewAttachRolePolicyRequest() (request *AttachRolePolicyRequest) { + request = &AttachRolePolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "AttachRolePolicy") + return +} + +func NewAttachRolePolicyResponse() (response *AttachRolePolicyResponse) { + response = &AttachRolePolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AttachRolePolicy)用于绑定策略到角色。 +func (c *Client) AttachRolePolicy(request *AttachRolePolicyRequest) (response *AttachRolePolicyResponse, err error) { + if request == nil { + request = NewAttachRolePolicyRequest() + } + response = NewAttachRolePolicyResponse() + err = c.Send(request, response) + return +} + +func NewAttachUserPolicyRequest() (request *AttachUserPolicyRequest) { + request = &AttachUserPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "AttachUserPolicy") + return +} + +func NewAttachUserPolicyResponse() (response *AttachUserPolicyResponse) { + response = &AttachUserPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(AttachUserPolicy)可用于绑定到用户的策略。 +func (c *Client) AttachUserPolicy(request *AttachUserPolicyRequest) (response *AttachUserPolicyResponse, err error) { + if request == nil { + request = NewAttachUserPolicyRequest() + } + response = NewAttachUserPolicyResponse() + err = c.Send(request, response) + return +} + +func NewConsumeCustomMFATokenRequest() (request *ConsumeCustomMFATokenRequest) { + request = &ConsumeCustomMFATokenRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ConsumeCustomMFAToken") + return +} + +func NewConsumeCustomMFATokenResponse() (response *ConsumeCustomMFATokenResponse) { + response = &ConsumeCustomMFATokenResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 验证自定义多因子Token +func (c *Client) ConsumeCustomMFAToken(request *ConsumeCustomMFATokenRequest) (response *ConsumeCustomMFATokenResponse, err error) { + if request == nil { + request = NewConsumeCustomMFATokenRequest() + } + response = NewConsumeCustomMFATokenResponse() + err = c.Send(request, response) + return +} + +func NewCreateGroupRequest() (request *CreateGroupRequest) { + request = &CreateGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "CreateGroup") + return +} + +func NewCreateGroupResponse() (response *CreateGroupResponse) { + response = &CreateGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 创建用户组 +func (c *Client) CreateGroup(request *CreateGroupRequest) (response *CreateGroupResponse, err error) { + if request == nil { + request = NewCreateGroupRequest() + } + response = NewCreateGroupResponse() + err = c.Send(request, response) + return +} + +func NewCreatePolicyRequest() (request *CreatePolicyRequest) { + request = &CreatePolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "CreatePolicy") + return +} + +func NewCreatePolicyResponse() (response *CreatePolicyResponse) { + response = &CreatePolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreatePolicy)可用于创建策略。 +func (c *Client) CreatePolicy(request *CreatePolicyRequest) (response *CreatePolicyResponse, err error) { + if request == nil { + request = NewCreatePolicyRequest() + } + response = NewCreatePolicyResponse() + err = c.Send(request, response) + return +} + +func NewCreateRoleRequest() (request *CreateRoleRequest) { + request = &CreateRoleRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "CreateRole") + return +} + +func NewCreateRoleResponse() (response *CreateRoleResponse) { + response = &CreateRoleResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(CreateRole)用于创建角色。 +func (c *Client) CreateRole(request *CreateRoleRequest) (response *CreateRoleResponse, err error) { + if request == nil { + request = NewCreateRoleRequest() + } + response = NewCreateRoleResponse() + err = c.Send(request, response) + return +} + +func NewCreateSAMLProviderRequest() (request *CreateSAMLProviderRequest) { + request = &CreateSAMLProviderRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "CreateSAMLProvider") + return +} + +func NewCreateSAMLProviderResponse() (response *CreateSAMLProviderResponse) { + response = &CreateSAMLProviderResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 创建SAML身份提供商 +func (c *Client) CreateSAMLProvider(request *CreateSAMLProviderRequest) (response *CreateSAMLProviderResponse, err error) { + if request == nil { + request = NewCreateSAMLProviderRequest() + } + response = NewCreateSAMLProviderResponse() + err = c.Send(request, response) + return +} + +func NewDeleteGroupRequest() (request *DeleteGroupRequest) { + request = &DeleteGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DeleteGroup") + return +} + +func NewDeleteGroupResponse() (response *DeleteGroupResponse) { + response = &DeleteGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除用户组 +func (c *Client) DeleteGroup(request *DeleteGroupRequest) (response *DeleteGroupResponse, err error) { + if request == nil { + request = NewDeleteGroupRequest() + } + response = NewDeleteGroupResponse() + err = c.Send(request, response) + return +} + +func NewDeletePolicyRequest() (request *DeletePolicyRequest) { + request = &DeletePolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DeletePolicy") + return +} + +func NewDeletePolicyResponse() (response *DeletePolicyResponse) { + response = &DeletePolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeletePolicy)可用于删除策略。 +func (c *Client) DeletePolicy(request *DeletePolicyRequest) (response *DeletePolicyResponse, err error) { + if request == nil { + request = NewDeletePolicyRequest() + } + response = NewDeletePolicyResponse() + err = c.Send(request, response) + return +} + +func NewDeleteRoleRequest() (request *DeleteRoleRequest) { + request = &DeleteRoleRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DeleteRole") + return +} + +func NewDeleteRoleResponse() (response *DeleteRoleResponse) { + response = &DeleteRoleResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DeleteRole)用于删除指定角色。 +func (c *Client) DeleteRole(request *DeleteRoleRequest) (response *DeleteRoleResponse, err error) { + if request == nil { + request = NewDeleteRoleRequest() + } + response = NewDeleteRoleResponse() + err = c.Send(request, response) + return +} + +func NewDeleteSAMLProviderRequest() (request *DeleteSAMLProviderRequest) { + request = &DeleteSAMLProviderRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DeleteSAMLProvider") + return +} + +func NewDeleteSAMLProviderResponse() (response *DeleteSAMLProviderResponse) { + response = &DeleteSAMLProviderResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除SAML身份提供商 +func (c *Client) DeleteSAMLProvider(request *DeleteSAMLProviderRequest) (response *DeleteSAMLProviderResponse, err error) { + if request == nil { + request = NewDeleteSAMLProviderRequest() + } + response = NewDeleteSAMLProviderResponse() + err = c.Send(request, response) + return +} + +func NewDeleteUserRequest() (request *DeleteUserRequest) { + request = &DeleteUserRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DeleteUser") + return +} + +func NewDeleteUserResponse() (response *DeleteUserResponse) { + response = &DeleteUserResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 删除子用户 +func (c *Client) DeleteUser(request *DeleteUserRequest) (response *DeleteUserResponse, err error) { + if request == nil { + request = NewDeleteUserRequest() + } + response = NewDeleteUserResponse() + err = c.Send(request, response) + return +} + +func NewDescribeRoleListRequest() (request *DescribeRoleListRequest) { + request = &DescribeRoleListRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DescribeRoleList") + return +} + +func NewDescribeRoleListResponse() (response *DescribeRoleListResponse) { + response = &DescribeRoleListResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DescribeRoleList)用于获取账号下的角色列表。 +func (c *Client) DescribeRoleList(request *DescribeRoleListRequest) (response *DescribeRoleListResponse, err error) { + if request == nil { + request = NewDescribeRoleListRequest() + } + response = NewDescribeRoleListResponse() + err = c.Send(request, response) + return +} + +func NewDetachGroupPolicyRequest() (request *DetachGroupPolicyRequest) { + request = &DetachGroupPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DetachGroupPolicy") + return +} + +func NewDetachGroupPolicyResponse() (response *DetachGroupPolicyResponse) { + response = &DetachGroupPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DetachGroupPolicy)可用于解除绑定到用户组的策略。 +func (c *Client) DetachGroupPolicy(request *DetachGroupPolicyRequest) (response *DetachGroupPolicyResponse, err error) { + if request == nil { + request = NewDetachGroupPolicyRequest() + } + response = NewDetachGroupPolicyResponse() + err = c.Send(request, response) + return +} + +func NewDetachRolePolicyRequest() (request *DetachRolePolicyRequest) { + request = &DetachRolePolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DetachRolePolicy") + return +} + +func NewDetachRolePolicyResponse() (response *DetachRolePolicyResponse) { + response = &DetachRolePolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DetachRolePolicy)用于解除绑定角色的策略。 +func (c *Client) DetachRolePolicy(request *DetachRolePolicyRequest) (response *DetachRolePolicyResponse, err error) { + if request == nil { + request = NewDetachRolePolicyRequest() + } + response = NewDetachRolePolicyResponse() + err = c.Send(request, response) + return +} + +func NewDetachUserPolicyRequest() (request *DetachUserPolicyRequest) { + request = &DetachUserPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "DetachUserPolicy") + return +} + +func NewDetachUserPolicyResponse() (response *DetachUserPolicyResponse) { + response = &DetachUserPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(DetachUserPolicy)可用于解除绑定到用户的策略。 +func (c *Client) DetachUserPolicy(request *DetachUserPolicyRequest) (response *DetachUserPolicyResponse, err error) { + if request == nil { + request = NewDetachUserPolicyRequest() + } + response = NewDetachUserPolicyResponse() + err = c.Send(request, response) + return +} + +func NewGetCustomMFATokenInfoRequest() (request *GetCustomMFATokenInfoRequest) { + request = &GetCustomMFATokenInfoRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "GetCustomMFATokenInfo") + return +} + +func NewGetCustomMFATokenInfoResponse() (response *GetCustomMFATokenInfoResponse) { + response = &GetCustomMFATokenInfoResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 获取自定义多因子Token关联信息 +func (c *Client) GetCustomMFATokenInfo(request *GetCustomMFATokenInfoRequest) (response *GetCustomMFATokenInfoResponse, err error) { + if request == nil { + request = NewGetCustomMFATokenInfoRequest() + } + response = NewGetCustomMFATokenInfoResponse() + err = c.Send(request, response) + return +} + +func NewGetGroupRequest() (request *GetGroupRequest) { + request = &GetGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "GetGroup") + return +} + +func NewGetGroupResponse() (response *GetGroupResponse) { + response = &GetGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询用户组详情 +func (c *Client) GetGroup(request *GetGroupRequest) (response *GetGroupResponse, err error) { + if request == nil { + request = NewGetGroupRequest() + } + response = NewGetGroupResponse() + err = c.Send(request, response) + return +} + +func NewGetPolicyRequest() (request *GetPolicyRequest) { + request = &GetPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "GetPolicy") + return +} + +func NewGetPolicyResponse() (response *GetPolicyResponse) { + response = &GetPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(GetPolicy)可用于查询查看策略详情。 +func (c *Client) GetPolicy(request *GetPolicyRequest) (response *GetPolicyResponse, err error) { + if request == nil { + request = NewGetPolicyRequest() + } + response = NewGetPolicyResponse() + err = c.Send(request, response) + return +} + +func NewGetRoleRequest() (request *GetRoleRequest) { + request = &GetRoleRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "GetRole") + return +} + +func NewGetRoleResponse() (response *GetRoleResponse) { + response = &GetRoleResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(GetRole)用于获取指定角色的详细信息。 +func (c *Client) GetRole(request *GetRoleRequest) (response *GetRoleResponse, err error) { + if request == nil { + request = NewGetRoleRequest() + } + response = NewGetRoleResponse() + err = c.Send(request, response) + return +} + +func NewGetSAMLProviderRequest() (request *GetSAMLProviderRequest) { + request = &GetSAMLProviderRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "GetSAMLProvider") + return +} + +func NewGetSAMLProviderResponse() (response *GetSAMLProviderResponse) { + response = &GetSAMLProviderResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询SAML身份提供商详情 +func (c *Client) GetSAMLProvider(request *GetSAMLProviderRequest) (response *GetSAMLProviderResponse, err error) { + if request == nil { + request = NewGetSAMLProviderRequest() + } + response = NewGetSAMLProviderResponse() + err = c.Send(request, response) + return +} + +func NewGetUserRequest() (request *GetUserRequest) { + request = &GetUserRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "GetUser") + return +} + +func NewGetUserResponse() (response *GetUserResponse) { + response = &GetUserResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询子用户 +func (c *Client) GetUser(request *GetUserRequest) (response *GetUserResponse, err error) { + if request == nil { + request = NewGetUserRequest() + } + response = NewGetUserResponse() + err = c.Send(request, response) + return +} + +func NewListAttachedGroupPoliciesRequest() (request *ListAttachedGroupPoliciesRequest) { + request = &ListAttachedGroupPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListAttachedGroupPolicies") + return +} + +func NewListAttachedGroupPoliciesResponse() (response *ListAttachedGroupPoliciesResponse) { + response = &ListAttachedGroupPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ListAttachedGroupPolicies)可用于查询用户组关联的策略列表。 +func (c *Client) ListAttachedGroupPolicies(request *ListAttachedGroupPoliciesRequest) (response *ListAttachedGroupPoliciesResponse, err error) { + if request == nil { + request = NewListAttachedGroupPoliciesRequest() + } + response = NewListAttachedGroupPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewListAttachedRolePoliciesRequest() (request *ListAttachedRolePoliciesRequest) { + request = &ListAttachedRolePoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListAttachedRolePolicies") + return +} + +func NewListAttachedRolePoliciesResponse() (response *ListAttachedRolePoliciesResponse) { + response = &ListAttachedRolePoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ListAttachedRolePolicies)用于获取角色绑定的策略列表。 +func (c *Client) ListAttachedRolePolicies(request *ListAttachedRolePoliciesRequest) (response *ListAttachedRolePoliciesResponse, err error) { + if request == nil { + request = NewListAttachedRolePoliciesRequest() + } + response = NewListAttachedRolePoliciesResponse() + err = c.Send(request, response) + return +} + +func NewListAttachedUserPoliciesRequest() (request *ListAttachedUserPoliciesRequest) { + request = &ListAttachedUserPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListAttachedUserPolicies") + return +} + +func NewListAttachedUserPoliciesResponse() (response *ListAttachedUserPoliciesResponse) { + response = &ListAttachedUserPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ListAttachedUserPolicies)可用于查询子账号关联的策略列表。 +func (c *Client) ListAttachedUserPolicies(request *ListAttachedUserPoliciesRequest) (response *ListAttachedUserPoliciesResponse, err error) { + if request == nil { + request = NewListAttachedUserPoliciesRequest() + } + response = NewListAttachedUserPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewListEntitiesForPolicyRequest() (request *ListEntitiesForPolicyRequest) { + request = &ListEntitiesForPolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListEntitiesForPolicy") + return +} + +func NewListEntitiesForPolicyResponse() (response *ListEntitiesForPolicyResponse) { + response = &ListEntitiesForPolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ListEntitiesForPolicy)可用于查询策略关联的实体列表。 +func (c *Client) ListEntitiesForPolicy(request *ListEntitiesForPolicyRequest) (response *ListEntitiesForPolicyResponse, err error) { + if request == nil { + request = NewListEntitiesForPolicyRequest() + } + response = NewListEntitiesForPolicyResponse() + err = c.Send(request, response) + return +} + +func NewListGroupsRequest() (request *ListGroupsRequest) { + request = &ListGroupsRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListGroups") + return +} + +func NewListGroupsResponse() (response *ListGroupsResponse) { + response = &ListGroupsResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询用户组列表 +func (c *Client) ListGroups(request *ListGroupsRequest) (response *ListGroupsResponse, err error) { + if request == nil { + request = NewListGroupsRequest() + } + response = NewListGroupsResponse() + err = c.Send(request, response) + return +} + +func NewListGroupsForUserRequest() (request *ListGroupsForUserRequest) { + request = &ListGroupsForUserRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListGroupsForUser") + return +} + +func NewListGroupsForUserResponse() (response *ListGroupsForUserResponse) { + response = &ListGroupsForUserResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 列出用户关联的用户组 +func (c *Client) ListGroupsForUser(request *ListGroupsForUserRequest) (response *ListGroupsForUserResponse, err error) { + if request == nil { + request = NewListGroupsForUserRequest() + } + response = NewListGroupsForUserResponse() + err = c.Send(request, response) + return +} + +func NewListPoliciesRequest() (request *ListPoliciesRequest) { + request = &ListPoliciesRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListPolicies") + return +} + +func NewListPoliciesResponse() (response *ListPoliciesResponse) { + response = &ListPoliciesResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(ListPolicies)可用于查询策略列表 +func (c *Client) ListPolicies(request *ListPoliciesRequest) (response *ListPoliciesResponse, err error) { + if request == nil { + request = NewListPoliciesRequest() + } + response = NewListPoliciesResponse() + err = c.Send(request, response) + return +} + +func NewListSAMLProvidersRequest() (request *ListSAMLProvidersRequest) { + request = &ListSAMLProvidersRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListSAMLProviders") + return +} + +func NewListSAMLProvidersResponse() (response *ListSAMLProvidersResponse) { + response = &ListSAMLProvidersResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询SAML身份提供商列表 +func (c *Client) ListSAMLProviders(request *ListSAMLProvidersRequest) (response *ListSAMLProvidersResponse, err error) { + if request == nil { + request = NewListSAMLProvidersRequest() + } + response = NewListSAMLProvidersResponse() + err = c.Send(request, response) + return +} + +func NewListUsersRequest() (request *ListUsersRequest) { + request = &ListUsersRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListUsers") + return +} + +func NewListUsersResponse() (response *ListUsersResponse) { + response = &ListUsersResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 拉取子用户 +func (c *Client) ListUsers(request *ListUsersRequest) (response *ListUsersResponse, err error) { + if request == nil { + request = NewListUsersRequest() + } + response = NewListUsersResponse() + err = c.Send(request, response) + return +} + +func NewListUsersForGroupRequest() (request *ListUsersForGroupRequest) { + request = &ListUsersForGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "ListUsersForGroup") + return +} + +func NewListUsersForGroupResponse() (response *ListUsersForGroupResponse) { + response = &ListUsersForGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 查询用户组关联的用户列表 +func (c *Client) ListUsersForGroup(request *ListUsersForGroupRequest) (response *ListUsersForGroupResponse, err error) { + if request == nil { + request = NewListUsersForGroupRequest() + } + response = NewListUsersForGroupResponse() + err = c.Send(request, response) + return +} + +func NewRemoveUserFromGroupRequest() (request *RemoveUserFromGroupRequest) { + request = &RemoveUserFromGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "RemoveUserFromGroup") + return +} + +func NewRemoveUserFromGroupResponse() (response *RemoveUserFromGroupResponse) { + response = &RemoveUserFromGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 从用户组删除用户 +func (c *Client) RemoveUserFromGroup(request *RemoveUserFromGroupRequest) (response *RemoveUserFromGroupResponse, err error) { + if request == nil { + request = NewRemoveUserFromGroupRequest() + } + response = NewRemoveUserFromGroupResponse() + err = c.Send(request, response) + return +} + +func NewSetFlagRequest() (request *SetFlagRequest) { + request = &SetFlagRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "SetFlag") + return +} + +func NewSetFlagResponse() (response *SetFlagResponse) { + response = &SetFlagResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 设置用户的登录,敏感操作,异步登录设置 +func (c *Client) SetFlag(request *SetFlagRequest) (response *SetFlagResponse, err error) { + if request == nil { + request = NewSetFlagRequest() + } + response = NewSetFlagResponse() + err = c.Send(request, response) + return +} + +func NewUpdateAssumeRolePolicyRequest() (request *UpdateAssumeRolePolicyRequest) { + request = &UpdateAssumeRolePolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "UpdateAssumeRolePolicy") + return +} + +func NewUpdateAssumeRolePolicyResponse() (response *UpdateAssumeRolePolicyResponse) { + response = &UpdateAssumeRolePolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(UpdateAssumeRolePolicy)用于修改角色信任策略的策略文档。 +func (c *Client) UpdateAssumeRolePolicy(request *UpdateAssumeRolePolicyRequest) (response *UpdateAssumeRolePolicyResponse, err error) { + if request == nil { + request = NewUpdateAssumeRolePolicyRequest() + } + response = NewUpdateAssumeRolePolicyResponse() + err = c.Send(request, response) + return +} + +func NewUpdateGroupRequest() (request *UpdateGroupRequest) { + request = &UpdateGroupRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "UpdateGroup") + return +} + +func NewUpdateGroupResponse() (response *UpdateGroupResponse) { + response = &UpdateGroupResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 更新用户组 +func (c *Client) UpdateGroup(request *UpdateGroupRequest) (response *UpdateGroupResponse, err error) { + if request == nil { + request = NewUpdateGroupRequest() + } + response = NewUpdateGroupResponse() + err = c.Send(request, response) + return +} + +func NewUpdatePolicyRequest() (request *UpdatePolicyRequest) { + request = &UpdatePolicyRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "UpdatePolicy") + return +} + +func NewUpdatePolicyResponse() (response *UpdatePolicyResponse) { + response = &UpdatePolicyResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(UpdatePolicy )可用于更新策略。 +func (c *Client) UpdatePolicy(request *UpdatePolicyRequest) (response *UpdatePolicyResponse, err error) { + if request == nil { + request = NewUpdatePolicyRequest() + } + response = NewUpdatePolicyResponse() + err = c.Send(request, response) + return +} + +func NewUpdateRoleDescriptionRequest() (request *UpdateRoleDescriptionRequest) { + request = &UpdateRoleDescriptionRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "UpdateRoleDescription") + return +} + +func NewUpdateRoleDescriptionResponse() (response *UpdateRoleDescriptionResponse) { + response = &UpdateRoleDescriptionResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 本接口(UpdateRoleDescription)用于修改角色的描述信息。 +func (c *Client) UpdateRoleDescription(request *UpdateRoleDescriptionRequest) (response *UpdateRoleDescriptionResponse, err error) { + if request == nil { + request = NewUpdateRoleDescriptionRequest() + } + response = NewUpdateRoleDescriptionResponse() + err = c.Send(request, response) + return +} + +func NewUpdateSAMLProviderRequest() (request *UpdateSAMLProviderRequest) { + request = &UpdateSAMLProviderRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "UpdateSAMLProvider") + return +} + +func NewUpdateSAMLProviderResponse() (response *UpdateSAMLProviderResponse) { + response = &UpdateSAMLProviderResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 更新SAML身份提供商信息 +func (c *Client) UpdateSAMLProvider(request *UpdateSAMLProviderRequest) (response *UpdateSAMLProviderResponse, err error) { + if request == nil { + request = NewUpdateSAMLProviderRequest() + } + response = NewUpdateSAMLProviderResponse() + err = c.Send(request, response) + return +} + +func NewUpdateUserRequest() (request *UpdateUserRequest) { + request = &UpdateUserRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + request.Init().WithApiInfo("cam", APIVersion, "UpdateUser") + return +} + +func NewUpdateUserResponse() (response *UpdateUserResponse) { + response = &UpdateUserResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return +} + +// 更新子用户 +func (c *Client) UpdateUser(request *UpdateUserRequest) (response *UpdateUserResponse, err error) { + if request == nil { + request = NewUpdateUserRequest() + } + response = NewUpdateUserResponse() + err = c.Send(request, response) + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116/models.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116/models.go new file mode 100644 index 0000000000..db4e9af8c6 --- /dev/null +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam/v20190116/models.go @@ -0,0 +1,2125 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v20190116 + +import ( + "encoding/json" + + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" +) + +type AddUserRequest struct { + *tchttp.BaseRequest + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` + + // 子用户备注 + Remark *string `json:"Remark,omitempty" name:"Remark"` + + // 子用户是否可以登录控制台。传0子用户无法登录控制台,传1子用户可以登录控制台。 + ConsoleLogin *uint64 `json:"ConsoleLogin,omitempty" name:"ConsoleLogin"` + + // 是否生成子用户密钥。传0不生成子用户密钥,传1生成子用户密钥。 + UseApi *uint64 `json:"UseApi,omitempty" name:"UseApi"` + + // 子用户控制台登录密码,若未进行密码规则设置则默认密码规则为8位以上同时包含大写小字母、数字和特殊字符。只有可以登录控制台时才有效,如果传空并且上面指定允许登录控制台,则自动生成随机密码,随机密码规则为32位包含大写小字母、数字和特殊字符。 + Password *string `json:"Password,omitempty" name:"Password"` + + // 子用户是否要在下次登录时重置密码。传0子用户下次登录控制台不需重置密码,传1子用户下次登录控制台需要重置密码。 + NeedResetPassword *uint64 `json:"NeedResetPassword,omitempty" name:"NeedResetPassword"` + + // 手机号 + PhoneNum *string `json:"PhoneNum,omitempty" name:"PhoneNum"` + + // 区号 + CountryCode *string `json:"CountryCode,omitempty" name:"CountryCode"` + + // 邮箱 + Email *string `json:"Email,omitempty" name:"Email"` +} + +func (r *AddUserRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AddUserRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AddUserResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 子用户 UIN + Uin *uint64 `json:"Uin,omitempty" name:"Uin"` + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` + + // 如果输入参数组合为自动生成随机密码,则返回生成的密码 + Password *string `json:"Password,omitempty" name:"Password"` + + // 子用户密钥 ID + SecretId *string `json:"SecretId,omitempty" name:"SecretId"` + + // 子用户密钥 Key + SecretKey *string `json:"SecretKey,omitempty" name:"SecretKey"` + + // 子用户 UID + Uid *uint64 `json:"Uid,omitempty" name:"Uid"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *AddUserResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AddUserResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AddUserToGroupRequest struct { + *tchttp.BaseRequest + + // 添加的子用户 UID 和用户组 ID 关联关系 + Info []*GroupIdOfUidInfo `json:"Info,omitempty" name:"Info" list` +} + +func (r *AddUserToGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AddUserToGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AddUserToGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *AddUserToGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AddUserToGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachEntityOfPolicy struct { + + // 实体ID + Id *string `json:"Id,omitempty" name:"Id"` + + // 实体名称 + // 注意:此字段可能返回 null,表示取不到有效值。 + Name *string `json:"Name,omitempty" name:"Name"` + + // 实体Uin + // 注意:此字段可能返回 null,表示取不到有效值。 + Uin *uint64 `json:"Uin,omitempty" name:"Uin"` + + // 关联类型。1 用户关联 ; 2 用户组关联 + RelatedType *uint64 `json:"RelatedType,omitempty" name:"RelatedType"` +} + +type AttachGroupPolicyRequest struct { + *tchttp.BaseRequest + + // 策略 id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 用户组 id + AttachGroupId *uint64 `json:"AttachGroupId,omitempty" name:"AttachGroupId"` +} + +func (r *AttachGroupPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachGroupPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachGroupPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *AttachGroupPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachGroupPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachPolicyInfo struct { + + // 策略id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 策略名称 + // 注意:此字段可能返回 null,表示取不到有效值。 + PolicyName *string `json:"PolicyName,omitempty" name:"PolicyName"` + + // 创建时间 + // 注意:此字段可能返回 null,表示取不到有效值。 + AddTime *string `json:"AddTime,omitempty" name:"AddTime"` + + // 创建来源,1 通过控制台创建, 2 通过策略语法创建。 + // 注意:此字段可能返回 null,表示取不到有效值。 + CreateMode *uint64 `json:"CreateMode,omitempty" name:"CreateMode"` + + // 取值为user和QCS + // 注意:此字段可能返回 null,表示取不到有效值。 + PolicyType *string `json:"PolicyType,omitempty" name:"PolicyType"` +} + +type AttachRolePolicyRequest struct { + *tchttp.BaseRequest + + // 策略ID + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 角色ID,用于指定角色,入参 AttachRoleId 与 AttachRoleName 二选一 + AttachRoleId *string `json:"AttachRoleId,omitempty" name:"AttachRoleId"` + + // 角色名称,用于指定角色,入参 AttachRoleId 与 AttachRoleName 二选一 + AttachRoleName *string `json:"AttachRoleName,omitempty" name:"AttachRoleName"` +} + +func (r *AttachRolePolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachRolePolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachRolePolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *AttachRolePolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachRolePolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachUserPolicyRequest struct { + *tchttp.BaseRequest + + // 策略 id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 子账号 uin + AttachUin *uint64 `json:"AttachUin,omitempty" name:"AttachUin"` +} + +func (r *AttachUserPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachUserPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachUserPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *AttachUserPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *AttachUserPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type AttachedPolicyOfRole struct { + + // 策略ID + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 策略名称 + PolicyName *string `json:"PolicyName,omitempty" name:"PolicyName"` + + // 绑定时间 + AddTime *string `json:"AddTime,omitempty" name:"AddTime"` + + // 策略类型,User表示自定义策略,QCS表示预设策略 + // 注意:此字段可能返回 null,表示取不到有效值。 + PolicyType *string `json:"PolicyType,omitempty" name:"PolicyType"` + + // 策略创建方式,1表示按产品功能或项目权限创建,其他表示按策略语法创建 + CreateMode *uint64 `json:"CreateMode,omitempty" name:"CreateMode"` +} + +type ConsumeCustomMFATokenRequest struct { + *tchttp.BaseRequest + + // 自定义多因子验证Token + MFAToken *string `json:"MFAToken,omitempty" name:"MFAToken"` +} + +func (r *ConsumeCustomMFATokenRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ConsumeCustomMFATokenRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ConsumeCustomMFATokenResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ConsumeCustomMFATokenResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ConsumeCustomMFATokenResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateGroupRequest struct { + *tchttp.BaseRequest + + // 用户组名 + GroupName *string `json:"GroupName,omitempty" name:"GroupName"` + + // 用户组描述 + Remark *string `json:"Remark,omitempty" name:"Remark"` +} + +func (r *CreateGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 用户组 ID + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreatePolicyRequest struct { + *tchttp.BaseRequest + + // 策略名 + PolicyName *string `json:"PolicyName,omitempty" name:"PolicyName"` + + // 策略文档 + PolicyDocument *string `json:"PolicyDocument,omitempty" name:"PolicyDocument"` + + // 策略描述 + Description *string `json:"Description,omitempty" name:"Description"` +} + +func (r *CreatePolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreatePolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreatePolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 新增策略id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreatePolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreatePolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateRoleRequest struct { + *tchttp.BaseRequest + + // 角色名称 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` + + // 策略文档 + PolicyDocument *string `json:"PolicyDocument,omitempty" name:"PolicyDocument"` + + // 角色描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // 是否允许登录 + ConsoleLogin *uint64 `json:"ConsoleLogin,omitempty" name:"ConsoleLogin"` +} + +func (r *CreateRoleRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateRoleRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateRoleResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 角色ID + // 注意:此字段可能返回 null,表示取不到有效值。 + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateRoleResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateRoleResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSAMLProviderRequest struct { + *tchttp.BaseRequest + + // SAML身份提供商名称 + Name *string `json:"Name,omitempty" name:"Name"` + + // SAML身份提供商描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // SAML身份提供商Base64编码的元数据文档 + SAMLMetadataDocument *string `json:"SAMLMetadataDocument,omitempty" name:"SAMLMetadataDocument"` +} + +func (r *CreateSAMLProviderRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSAMLProviderRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type CreateSAMLProviderResponse struct { + *tchttp.BaseResponse + Response *struct { + + // SAML身份提供商资源描述符 + ProviderArn *string `json:"ProviderArn,omitempty" name:"ProviderArn"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *CreateSAMLProviderResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *CreateSAMLProviderResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteGroupRequest struct { + *tchttp.BaseRequest + + // 用户组 ID + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` +} + +func (r *DeleteGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeletePolicyRequest struct { + *tchttp.BaseRequest + + // 数组,数组成员是策略 id,支持批量删除策略 + PolicyId []*uint64 `json:"PolicyId,omitempty" name:"PolicyId" list` +} + +func (r *DeletePolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeletePolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeletePolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeletePolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeletePolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRoleRequest struct { + *tchttp.BaseRequest + + // 角色ID,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 角色名称,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` +} + +func (r *DeleteRoleRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteRoleRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRoleResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteRoleResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteRoleResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSAMLProviderRequest struct { + *tchttp.BaseRequest + + // SAML身份提供商名称 + Name *string `json:"Name,omitempty" name:"Name"` +} + +func (r *DeleteSAMLProviderRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSAMLProviderRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteSAMLProviderResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteSAMLProviderResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteSAMLProviderResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteUserRequest struct { + *tchttp.BaseRequest + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` +} + +func (r *DeleteUserRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteUserRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteUserResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DeleteUserResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DeleteUserResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRoleListRequest struct { + *tchttp.BaseRequest + + // 页码,从1开始 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页行数,不能大于200 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` +} + +func (r *DescribeRoleListRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRoleListRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRoleListResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 角色详情列表。 + // 注意:此字段可能返回 null,表示取不到有效值。 + List []*RoleInfo `json:"List,omitempty" name:"List" list` + + // 角色总数 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DescribeRoleListResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DescribeRoleListResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachGroupPolicyRequest struct { + *tchttp.BaseRequest + + // 策略 id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 用户组 id + DetachGroupId *uint64 `json:"DetachGroupId,omitempty" name:"DetachGroupId"` +} + +func (r *DetachGroupPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachGroupPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachGroupPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DetachGroupPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachGroupPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachRolePolicyRequest struct { + *tchttp.BaseRequest + + // 策略ID + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 角色ID,用于指定角色,入参 AttachRoleId 与 AttachRoleName 二选一 + DetachRoleId *string `json:"DetachRoleId,omitempty" name:"DetachRoleId"` + + // 角色名称,用于指定角色,入参 AttachRoleId 与 AttachRoleName 二选一 + DetachRoleName *string `json:"DetachRoleName,omitempty" name:"DetachRoleName"` +} + +func (r *DetachRolePolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachRolePolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachRolePolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DetachRolePolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachRolePolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachUserPolicyRequest struct { + *tchttp.BaseRequest + + // 策略 id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 子账号 uin + DetachUin *uint64 `json:"DetachUin,omitempty" name:"DetachUin"` +} + +func (r *DetachUserPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachUserPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DetachUserPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *DetachUserPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *DetachUserPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetCustomMFATokenInfoRequest struct { + *tchttp.BaseRequest + + // 自定义多因子验证Token + MFAToken *string `json:"MFAToken,omitempty" name:"MFAToken"` +} + +func (r *GetCustomMFATokenInfoRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetCustomMFATokenInfoRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetCustomMFATokenInfoResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 自定义多因子验证Token对应的帐号Id + Uin *uint64 `json:"Uin,omitempty" name:"Uin"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *GetCustomMFATokenInfoResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetCustomMFATokenInfoResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetGroupRequest struct { + *tchttp.BaseRequest + + // 用户组 ID + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` +} + +func (r *GetGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 用户组 ID + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` + + // 用户组名称 + GroupName *string `json:"GroupName,omitempty" name:"GroupName"` + + // 用户组成员数量 + GroupNum *uint64 `json:"GroupNum,omitempty" name:"GroupNum"` + + // 用户组描述 + Remark *string `json:"Remark,omitempty" name:"Remark"` + + // 用户组创建时间 + CreateTime *string `json:"CreateTime,omitempty" name:"CreateTime"` + + // 用户组成员信息 + UserInfo []*GroupMemberInfo `json:"UserInfo,omitempty" name:"UserInfo" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *GetGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetPolicyRequest struct { + *tchttp.BaseRequest + + // 策略Id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` +} + +func (r *GetPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 策略名 + // 注意:此字段可能返回 null,表示取不到有效值。 + PolicyName *string `json:"PolicyName,omitempty" name:"PolicyName"` + + // 策略描述 + // 注意:此字段可能返回 null,表示取不到有效值。 + Description *string `json:"Description,omitempty" name:"Description"` + + // 1 表示自定义策略,2 表示预设策略 + // 注意:此字段可能返回 null,表示取不到有效值。 + Type *uint64 `json:"Type,omitempty" name:"Type"` + + // 创建时间 + // 注意:此字段可能返回 null,表示取不到有效值。 + AddTime *string `json:"AddTime,omitempty" name:"AddTime"` + + // 最近更新时间 + // 注意:此字段可能返回 null,表示取不到有效值。 + UpdateTime *string `json:"UpdateTime,omitempty" name:"UpdateTime"` + + // 策略文档 + // 注意:此字段可能返回 null,表示取不到有效值。 + PolicyDocument *string `json:"PolicyDocument,omitempty" name:"PolicyDocument"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *GetPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetRoleRequest struct { + *tchttp.BaseRequest + + // 角色 ID,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 角色名,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` +} + +func (r *GetRoleRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetRoleRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetRoleResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 角色详情 + RoleInfo *RoleInfo `json:"RoleInfo,omitempty" name:"RoleInfo"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *GetRoleResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetRoleResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetSAMLProviderRequest struct { + *tchttp.BaseRequest + + // SAML身份提供商名称 + Name *string `json:"Name,omitempty" name:"Name"` +} + +func (r *GetSAMLProviderRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetSAMLProviderRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetSAMLProviderResponse struct { + *tchttp.BaseResponse + Response *struct { + + // SAML身份提供商名称 + Name *string `json:"Name,omitempty" name:"Name"` + + // SAML身份提供商描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // SAML身份提供商创建时间 + CreateTime *string `json:"CreateTime,omitempty" name:"CreateTime"` + + // SAML身份提供商上次修改时间 + ModifyTime *string `json:"ModifyTime,omitempty" name:"ModifyTime"` + + // SAML身份提供商元数据文档 + SAMLMetadata *string `json:"SAMLMetadata,omitempty" name:"SAMLMetadata"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *GetSAMLProviderResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetSAMLProviderResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetUserRequest struct { + *tchttp.BaseRequest + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` +} + +func (r *GetUserRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetUserRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GetUserResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 子用户用户 ID + Uin *uint64 `json:"Uin,omitempty" name:"Uin"` + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` + + // 子用户 UID + Uid *uint64 `json:"Uid,omitempty" name:"Uid"` + + // 子用户备注 + Remark *string `json:"Remark,omitempty" name:"Remark"` + + // 子用户能否登录控制台 + ConsoleLogin *uint64 `json:"ConsoleLogin,omitempty" name:"ConsoleLogin"` + + // 手机号 + PhoneNum *string `json:"PhoneNum,omitempty" name:"PhoneNum"` + + // 区号 + CountryCode *string `json:"CountryCode,omitempty" name:"CountryCode"` + + // 邮箱 + Email *string `json:"Email,omitempty" name:"Email"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *GetUserResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *GetUserResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type GroupIdOfUidInfo struct { + + // 子用户 UID + Uid *uint64 `json:"Uid,omitempty" name:"Uid"` + + // 用户组 ID + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` +} + +type GroupInfo struct { + + // 用户组 ID。 + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` + + // 用户组名称。 + GroupName *string `json:"GroupName,omitempty" name:"GroupName"` + + // 用户组创建时间。 + CreateTime *string `json:"CreateTime,omitempty" name:"CreateTime"` + + // 用户组描述。 + Remark *string `json:"Remark,omitempty" name:"Remark"` +} + +type GroupMemberInfo struct { + + // 子用户 Uid。 + Uid *uint64 `json:"Uid,omitempty" name:"Uid"` + + // 子用户 Uin。 + Uin *uint64 `json:"Uin,omitempty" name:"Uin"` + + // 子用户名称。 + Name *string `json:"Name,omitempty" name:"Name"` + + // 手机号。 + PhoneNum *string `json:"PhoneNum,omitempty" name:"PhoneNum"` + + // 手机区域代码。 + CountryCode *string `json:"CountryCode,omitempty" name:"CountryCode"` + + // 是否已验证手机。 + PhoneFlag *uint64 `json:"PhoneFlag,omitempty" name:"PhoneFlag"` + + // 邮箱地址。 + Email *string `json:"Email,omitempty" name:"Email"` + + // 是否已验证邮箱。 + EmailFlag *uint64 `json:"EmailFlag,omitempty" name:"EmailFlag"` + + // 用户类型。 + UserType *uint64 `json:"UserType,omitempty" name:"UserType"` + + // 创建时间。 + CreateTime *string `json:"CreateTime,omitempty" name:"CreateTime"` + + // 是否为主消息接收人。 + IsReceiverOwner *uint64 `json:"IsReceiverOwner,omitempty" name:"IsReceiverOwner"` +} + +type ListAttachedGroupPoliciesRequest struct { + *tchttp.BaseRequest + + // 用户组 id + TargetGroupId *uint64 `json:"TargetGroupId,omitempty" name:"TargetGroupId"` + + // 页码,默认值是 1,从 1 开始 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页大小,默认值是 20 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` +} + +func (r *ListAttachedGroupPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListAttachedGroupPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListAttachedGroupPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 策略总数 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 策略列表 + List []*AttachPolicyInfo `json:"List,omitempty" name:"List" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListAttachedGroupPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListAttachedGroupPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListAttachedRolePoliciesRequest struct { + *tchttp.BaseRequest + + // 页码,从 1 开始 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页行数,不能大于200 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` + + // 角色 ID。用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 角色名。用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` + + // 按策略类型过滤,User表示仅查询自定义策略,QCS表示仅查询预设策略 + PolicyType *string `json:"PolicyType,omitempty" name:"PolicyType"` +} + +func (r *ListAttachedRolePoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListAttachedRolePoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListAttachedRolePoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 角色关联的策略列表 + List []*AttachedPolicyOfRole `json:"List,omitempty" name:"List" list` + + // 角色关联的策略总数 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListAttachedRolePoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListAttachedRolePoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListAttachedUserPoliciesRequest struct { + *tchttp.BaseRequest + + // 子账号 uin + TargetUin *uint64 `json:"TargetUin,omitempty" name:"TargetUin"` + + // 页码,默认值是 1,从 1 开始 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页大小,默认值是 20 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` +} + +func (r *ListAttachedUserPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListAttachedUserPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListAttachedUserPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 策略总数 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 策略列表 + List []*AttachPolicyInfo `json:"List,omitempty" name:"List" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListAttachedUserPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListAttachedUserPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListEntitiesForPolicyRequest struct { + *tchttp.BaseRequest + + // 策略 id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 页码,默认值是 1,从 1 开始 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页大小,默认值是 20 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` + + // 可取值 'All'、'User'、'Group' 和 'Role','All' 表示获取所有实体类型,'User' 表示只获取子账号,'Group' 表示只获取用户组,'Role' 表示只获取角色,默认取 'All' + EntityFilter *string `json:"EntityFilter,omitempty" name:"EntityFilter"` +} + +func (r *ListEntitiesForPolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListEntitiesForPolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListEntitiesForPolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 实体总数 + // 注意:此字段可能返回 null,表示取不到有效值。 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 实体列表 + // 注意:此字段可能返回 null,表示取不到有效值。 + List []*AttachEntityOfPolicy `json:"List,omitempty" name:"List" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListEntitiesForPolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListEntitiesForPolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListGroupsForUserRequest struct { + *tchttp.BaseRequest + + // 子用户 UID + Uid *uint64 `json:"Uid,omitempty" name:"Uid"` + + // 每页数量。默认为20。 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` + + // 页码。默认为1。 + Page *uint64 `json:"Page,omitempty" name:"Page"` +} + +func (r *ListGroupsForUserRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListGroupsForUserRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListGroupsForUserResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 子用户加入的用户组总数 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 用户组信息 + GroupInfo []*GroupInfo `json:"GroupInfo,omitempty" name:"GroupInfo" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListGroupsForUserResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListGroupsForUserResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListGroupsRequest struct { + *tchttp.BaseRequest + + // 页码。默认为1。 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页数量。默认为20。 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` + + // 按用户组名称匹配。 + Keyword *string `json:"Keyword,omitempty" name:"Keyword"` +} + +func (r *ListGroupsRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListGroupsRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListGroupsResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 用户组总数。 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 用户组数组信息。 + GroupInfo []*GroupInfo `json:"GroupInfo,omitempty" name:"GroupInfo" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListGroupsResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListGroupsResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListPoliciesRequest struct { + *tchttp.BaseRequest + + // 每页数量,默认值是 20,必须大于 0 且小于或等于 200 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` + + // 页码,默认值是 1,从 1开始,不能大于 200 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 可取值 'All'、'QCS' 和 'Local','All' 获取所有策略,'QCS' 只获取预设策略,'Local' 只获取自定义策略,默认取 'All' + Scope *string `json:"Scope,omitempty" name:"Scope"` + + // 按策略名匹配 + Keyword *string `json:"Keyword,omitempty" name:"Keyword"` +} + +func (r *ListPoliciesRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListPoliciesRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListPoliciesResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 策略总数 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 策略数组,数组每个成员包括 policyId、policyName、addTime、type、description、 createMode 字段。其中: + // policyId:策略 id + // policyName:策略名 + // addTime:策略创建时间 + // type:1 表示自定义策略,2 表示预设策略 + // description:策略描述 + // createMode:1 表示按业务权限创建的策略,其他值表示可以查看策略语法和通过策略语法更新策略 + List []*StrategyInfo `json:"List,omitempty" name:"List" list` + + // 保留字段 + // 注意:此字段可能返回 null,表示取不到有效值。 + ServiceTypeList []*string `json:"ServiceTypeList,omitempty" name:"ServiceTypeList" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListPoliciesResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListPoliciesResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListSAMLProvidersRequest struct { + *tchttp.BaseRequest +} + +func (r *ListSAMLProvidersRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListSAMLProvidersRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListSAMLProvidersResponse struct { + *tchttp.BaseResponse + Response *struct { + + // SAML身份提供商总数 + TotalCount *int64 `json:"TotalCount,omitempty" name:"TotalCount"` + + // SAML身份提供商列表 + SAMLProviderSet []*SAMLProviderInfo `json:"SAMLProviderSet,omitempty" name:"SAMLProviderSet" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListSAMLProvidersResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListSAMLProvidersResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListUsersForGroupRequest struct { + *tchttp.BaseRequest + + // 用户组 ID。 + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` + + // 页码。默认为1。 + Page *uint64 `json:"Page,omitempty" name:"Page"` + + // 每页数量。默认为20。 + Rp *uint64 `json:"Rp,omitempty" name:"Rp"` +} + +func (r *ListUsersForGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListUsersForGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListUsersForGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 用户组关联的用户总数。 + TotalNum *uint64 `json:"TotalNum,omitempty" name:"TotalNum"` + + // 子用户信息。 + UserInfo []*GroupMemberInfo `json:"UserInfo,omitempty" name:"UserInfo" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListUsersForGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListUsersForGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListUsersRequest struct { + *tchttp.BaseRequest +} + +func (r *ListUsersRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListUsersRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ListUsersResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 子用户信息 + Data []*SubAccountInfo `json:"Data,omitempty" name:"Data" list` + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *ListUsersResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *ListUsersResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type LoginActionFlag struct { + + // 手机 + Phone *uint64 `json:"Phone,omitempty" name:"Phone"` + + // 硬token + Token *uint64 `json:"Token,omitempty" name:"Token"` + + // 软token + Stoken *uint64 `json:"Stoken,omitempty" name:"Stoken"` + + // 微信 + Wechat *uint64 `json:"Wechat,omitempty" name:"Wechat"` + + // 自定义 + Custom *uint64 `json:"Custom,omitempty" name:"Custom"` +} + +type OffsiteFlag struct { + + // 验证标识 + VerifyFlag *uint64 `json:"VerifyFlag,omitempty" name:"VerifyFlag"` + + // 手机通知 + NotifyPhone *uint64 `json:"NotifyPhone,omitempty" name:"NotifyPhone"` + + // 邮箱通知 + NotifyEmail *int64 `json:"NotifyEmail,omitempty" name:"NotifyEmail"` + + // 微信通知 + NotifyWechat *uint64 `json:"NotifyWechat,omitempty" name:"NotifyWechat"` +} + +type RemoveUserFromGroupRequest struct { + *tchttp.BaseRequest + + // 要删除的用户 UID和用户组 ID对应数组 + Info []*GroupIdOfUidInfo `json:"Info,omitempty" name:"Info" list` +} + +func (r *RemoveUserFromGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RemoveUserFromGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RemoveUserFromGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *RemoveUserFromGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *RemoveUserFromGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RoleInfo struct { + + // 角色ID + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 角色名称 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` + + // 角色的策略文档 + PolicyDocument *string `json:"PolicyDocument,omitempty" name:"PolicyDocument"` + + // 角色描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // 角色的创建时间 + AddTime *string `json:"AddTime,omitempty" name:"AddTime"` + + // 角色的最近一次时间 + UpdateTime *string `json:"UpdateTime,omitempty" name:"UpdateTime"` + + // 角色是否允许登录 + ConsoleLogin *uint64 `json:"ConsoleLogin,omitempty" name:"ConsoleLogin"` +} + +type SAMLProviderInfo struct { + + // SAML身份提供商名称 + Name *string `json:"Name,omitempty" name:"Name"` + + // SAML身份提供商描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // SAML身份提供商创建时间 + CreateTime *string `json:"CreateTime,omitempty" name:"CreateTime"` + + // SAML身份提供商上次修改时间 + ModifyTime *string `json:"ModifyTime,omitempty" name:"ModifyTime"` +} + +type SetFlagRequest struct { + *tchttp.BaseRequest + + // 设置用户的uin + OpUin *uint64 `json:"OpUin,omitempty" name:"OpUin"` + + // 登录设置 + LoginFlag *LoginActionFlag `json:"LoginFlag,omitempty" name:"LoginFlag"` + + // 敏感操作设置 + ActionFlag *LoginActionFlag `json:"ActionFlag,omitempty" name:"ActionFlag"` + + // 异地登录设置 + OffsiteFlag *OffsiteFlag `json:"OffsiteFlag,omitempty" name:"OffsiteFlag"` + + // 是否需要充值mfa + NeedResetMfa *uint64 `json:"NeedResetMfa,omitempty" name:"NeedResetMfa"` +} + +func (r *SetFlagRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *SetFlagRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type SetFlagResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *SetFlagResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *SetFlagResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type StrategyInfo struct { + + // 策略ID。 + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 策略名称。 + PolicyName *string `json:"PolicyName,omitempty" name:"PolicyName"` + + // 策略创建时间。 + // 注意:此字段可能返回 null,表示取不到有效值。 + AddTime *string `json:"AddTime,omitempty" name:"AddTime"` + + // 策略类型。1 表示自定义策略,2 表示预设策略。 + Type *uint64 `json:"Type,omitempty" name:"Type"` + + // 策略描述。 + // 注意:此字段可能返回 null,表示取不到有效值。 + Description *string `json:"Description,omitempty" name:"Description"` + + // 创建来源,1 通过控制台创建, 2 通过策略语法创建。 + CreateMode *uint64 `json:"CreateMode,omitempty" name:"CreateMode"` + + // 关联的用户数 + Attachments *uint64 `json:"Attachments,omitempty" name:"Attachments"` + + // 策略关联的产品 + // 注意:此字段可能返回 null,表示取不到有效值。 + ServiceType *string `json:"ServiceType,omitempty" name:"ServiceType"` +} + +type SubAccountInfo struct { + + // 子用户用户 ID + Uin *uint64 `json:"Uin,omitempty" name:"Uin"` + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` + + // 子用户 UID + Uid *uint64 `json:"Uid,omitempty" name:"Uid"` + + // 子用户备注 + Remark *string `json:"Remark,omitempty" name:"Remark"` + + // 子用户能否登录控制台 + ConsoleLogin *uint64 `json:"ConsoleLogin,omitempty" name:"ConsoleLogin"` + + // 手机号 + PhoneNum *string `json:"PhoneNum,omitempty" name:"PhoneNum"` + + // 区号 + CountryCode *string `json:"CountryCode,omitempty" name:"CountryCode"` + + // 邮箱 + Email *string `json:"Email,omitempty" name:"Email"` +} + +type UpdateAssumeRolePolicyRequest struct { + *tchttp.BaseRequest + + // 策略文档 + PolicyDocument *string `json:"PolicyDocument,omitempty" name:"PolicyDocument"` + + // 角色ID,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 角色名称,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` +} + +func (r *UpdateAssumeRolePolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateAssumeRolePolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateAssumeRolePolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *UpdateAssumeRolePolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateAssumeRolePolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateGroupRequest struct { + *tchttp.BaseRequest + + // 用户组 ID + GroupId *uint64 `json:"GroupId,omitempty" name:"GroupId"` + + // 用户组名 + GroupName *string `json:"GroupName,omitempty" name:"GroupName"` + + // 用户组描述 + Remark *string `json:"Remark,omitempty" name:"Remark"` +} + +func (r *UpdateGroupRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateGroupRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateGroupResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *UpdateGroupResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateGroupResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdatePolicyRequest struct { + *tchttp.BaseRequest + + // 策略 id + PolicyId *uint64 `json:"PolicyId,omitempty" name:"PolicyId"` + + // 策略名 + PolicyName *string `json:"PolicyName,omitempty" name:"PolicyName"` + + // 策略描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // 策略文档 + PolicyDocument *string `json:"PolicyDocument,omitempty" name:"PolicyDocument"` +} + +func (r *UpdatePolicyRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdatePolicyRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdatePolicyResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *UpdatePolicyResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdatePolicyResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateRoleDescriptionRequest struct { + *tchttp.BaseRequest + + // 角色描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // 角色ID,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleId *string `json:"RoleId,omitempty" name:"RoleId"` + + // 角色名称,用于指定角色,入参 RoleId 与 RoleName 二选一 + RoleName *string `json:"RoleName,omitempty" name:"RoleName"` +} + +func (r *UpdateRoleDescriptionRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateRoleDescriptionRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateRoleDescriptionResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *UpdateRoleDescriptionResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateRoleDescriptionResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateSAMLProviderRequest struct { + *tchttp.BaseRequest + + // SAML身份提供商名称 + Name *string `json:"Name,omitempty" name:"Name"` + + // SAML身份提供商描述 + Description *string `json:"Description,omitempty" name:"Description"` + + // SAML身份提供商Base64编码的元数据文档 + SAMLMetadataDocument *string `json:"SAMLMetadataDocument,omitempty" name:"SAMLMetadataDocument"` +} + +func (r *UpdateSAMLProviderRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateSAMLProviderRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateSAMLProviderResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *UpdateSAMLProviderResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateSAMLProviderResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateUserRequest struct { + *tchttp.BaseRequest + + // 子用户用户名 + Name *string `json:"Name,omitempty" name:"Name"` + + // 子用户备注 + Remark *string `json:"Remark,omitempty" name:"Remark"` + + // 子用户是否可以登录控制台。传0子用户无法登录控制台,传1子用户可以登录控制台。 + ConsoleLogin *uint64 `json:"ConsoleLogin,omitempty" name:"ConsoleLogin"` + + // 子用户控制台登录密码,若未进行密码规则设置则默认密码规则为8位以上同时包含大写小字母、数字和特殊字符。只有可以登录控制台时才有效,如果传空并且上面指定允许登录控制台,则自动生成随机密码,随机密码规则为32位包含大写小字母、数字和特殊字符。 + Password *string `json:"Password,omitempty" name:"Password"` + + // 子用户是否要在下次登录时重置密码。传0子用户下次登录控制台不需重置密码,传1子用户下次登录控制台需要重置密码。 + NeedResetPassword *uint64 `json:"NeedResetPassword,omitempty" name:"NeedResetPassword"` + + // 手机号 + PhoneNum *string `json:"PhoneNum,omitempty" name:"PhoneNum"` + + // 区号 + CountryCode *string `json:"CountryCode,omitempty" name:"CountryCode"` + + // 邮箱 + Email *string `json:"Email,omitempty" name:"Email"` +} + +func (r *UpdateUserRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateUserRequest) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type UpdateUserResponse struct { + *tchttp.BaseResponse + Response *struct { + + // 唯一请求 ID,每次请求都会返回。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitempty" name:"RequestId"` + } `json:"Response"` +} + +func (r *UpdateUserResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +func (r *UpdateUserResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} diff --git a/website/docs/d/cam_group_memberships.html.markdown b/website/docs/d/cam_group_memberships.html.markdown new file mode 100644 index 0000000000..58f6dd9b0e --- /dev/null +++ b/website/docs/d/cam_group_memberships.html.markdown @@ -0,0 +1,36 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_group_memberships" +sidebar_current: "docs-tencentcloud-datasource-cam_group_memberships" +description: |- + Use this data source to query detailed information of CAM groups +--- + +# tencentcloud_cam_group_memberships + +Use this data source to query detailed information of CAM groups + +## Example Usage + +```hcl +data "tencentcloud_cam_group_memberships" "foo" { + group_id = "12515263" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `group_id` - (Optional) Id of CAM group to be queried. +* `result_output_file` - (Optional) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `membership_list` - A list of CAM group membership. Each element contains the following attributes: + * `group_id` - Id of CAM group. + * `user_ids` - Id set of the CAM group members. + + diff --git a/website/docs/d/cam_group_policy_attachments.html.markdown b/website/docs/d/cam_group_policy_attachments.html.markdown new file mode 100644 index 0000000000..2768ed8c63 --- /dev/null +++ b/website/docs/d/cam_group_policy_attachments.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_group_policy_attachments" +sidebar_current: "docs-tencentcloud-datasource-cam_group_policy_attachments" +description: |- + Use this data source to query detailed information of CAM group policy attachments +--- + +# tencentcloud_cam_group_policy_attachments + +Use this data source to query detailed information of CAM group policy attachments + +## Example Usage + +```hcl +data "tencentcloud_cam_group_policy_attachments" "foo" { + group_id = "12515263" + policy_id = "215153266" + policy_type = "QCS" + create_mode = 1 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `group_id` - (Required) Id of the attached CAM group to be queried. +* `create_mode` - (Optional) Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. +* `policy_id` - (Optional) Id of CAM policy to be queried. +* `policy_type` - (Optional) Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. +* `result_output_file` - (Optional) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `group_policy_attachment_list` - A list of CAM group policy attachments. Each element contains the following attributes: + * `create_mode` - Mode of Creation of the CAM group policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. + * `create_time` - Create time of the CAM group policy attachment. + * `group_id` - Id of CAM group. + * `policy_id` - Name of CAM group. + * `policy_name` - Name of the policy. + * `policy_type` - Type of the policy strategy. 'Group' means customer strategy and 'QCS' means preset strategy. + + diff --git a/website/docs/d/cam_groups.html.markdown b/website/docs/d/cam_groups.html.markdown new file mode 100644 index 0000000000..48fe8eeb1b --- /dev/null +++ b/website/docs/d/cam_groups.html.markdown @@ -0,0 +1,41 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_groups" +sidebar_current: "docs-tencentcloud-datasource-cam_groups" +description: |- + Use this data source to query detailed information of CAM groups +--- + +# tencentcloud_cam_groups + +Use this data source to query detailed information of CAM groups + +## Example Usage + +```hcl +data "tencentcloud_cam_groups" "foo" { + group_id = "12515263" + name = "cam-role-test" + remark = "test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `group_id` - (Optional) Id of CAM group to be queried. +* `name` - (Optional) Name of the CAM group to be queried. +* `remark` - (Optional) Description of the cam group. +* `result_output_file` - (Optional) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `group_list` - A list of CAM groups. Each element contains the following attributes: + * `create_time` - Create time of the CAM group. + * `name` - Name of CAM group. + * `remark` - Description of CAM group. + + diff --git a/website/docs/d/cam_policies.html.markdown b/website/docs/d/cam_policies.html.markdown new file mode 100644 index 0000000000..d8a0698202 --- /dev/null +++ b/website/docs/d/cam_policies.html.markdown @@ -0,0 +1,49 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_policies" +sidebar_current: "docs-tencentcloud-datasource-cam_policies" +description: |- + Use this data source to query detailed information of CAM policies +--- + +# tencentcloud_cam_policies + +Use this data source to query detailed information of CAM policies + +## Example Usage + +```hcl +data "tencentcloud_cam_policies" "foo" { + policy_id = "26655801" + name = "cam-policy-test" + type = 1 + create_mode = 1 + description = "test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `policy_id` - (Required) Id of CAM policy to be queried to be queried. +* `create_mode` - (Optional) Mode of creation of policy strategy. 1 means policy was created with console, and 2 means it was created by strategies. +* `description` - (Optional) The description of the CAM policy . +* `name` - (Optional) Name of the CAM policy to be queried. +* `result_output_file` - (Optional) Used to save results. +* `type` - (Optional) Type of the policy strategy. 1 means customer strategy and 2 means preset strategy. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `policy_list` - A list of CAM policies. Each element contains the following attributes: + * `attachments` - Number of attached users. + * `create_mode` - Mode of creation of policy strategy. 1 means policy was created with console, and 2 means it was created by strategies. + * `create_time` - Create time of the CAM policy. + * `description` - Description of CAM policy. + * `name` - Name of CAM policy. + * `service_type` - Name of attached products. + * `type` - Type of the policy strategy. 1 means customer strategy and 2 means preset strategy. + + diff --git a/website/docs/d/cam_role_policy_attachments.html.markdown b/website/docs/d/cam_role_policy_attachments.html.markdown new file mode 100644 index 0000000000..6f22629af5 --- /dev/null +++ b/website/docs/d/cam_role_policy_attachments.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_role_policy_attachments" +sidebar_current: "docs-tencentcloud-datasource-cam_role_policy_attachments" +description: |- + Use this data source to query detailed information of CAM role policy attachments +--- + +# tencentcloud_cam_role_policy_attachments + +Use this data source to query detailed information of CAM role policy attachments + +## Example Usage + +```hcl +data "tencentcloud_cam_role_policy_attachments" "foo" { + role_id = "4611686018427922725" + policy_id = "26800353" + policy_type = "QCS" + create_mode = 1 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `role_id` - (Required) Id of the attached CAM role to be queried. +* `create_mode` - (Optional) Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. +* `policy_id` - (Optional) Id of CAM policy to be queried. +* `policy_type` - (Optional) Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. +* `result_output_file` - (Optional) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `role_policy_attachment_list` - A list of CAM role policy attachments. Each element contains the following attributes: + * `create_mode` - Mode of Creation of the CAM role policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. + * `create_time` - Create time of the CAM role policy attachment. + * `policy_id` - Name of CAM role. + * `policy_name` - Name of the policy. + * `policy_type` - Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. + * `role_id` - Id of CAM role. + + diff --git a/website/docs/d/cam_roles.html.markdown b/website/docs/d/cam_roles.html.markdown new file mode 100644 index 0000000000..8ece887be0 --- /dev/null +++ b/website/docs/d/cam_roles.html.markdown @@ -0,0 +1,45 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_roles" +sidebar_current: "docs-tencentcloud-datasource-cam_roles" +description: |- + Use this data source to query detailed information of CAM roles +--- + +# tencentcloud_cam_roles + +Use this data source to query detailed information of CAM roles + +## Example Usage + +```hcl +data "tencentcloud_cam_roles" "foo" { + role_id = "14151513226" + name = "cam-role-test" + description = "test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `description` - (Optional) The description of the CAM role to be queried. +* `name` - (Optional) Name of the CAM policy to be queried. +* `result_output_file` - (Optional) Used to save results. +* `role_id` - (Optional) Id of the CAM role to be queried. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `role_list` - A list of CAM roles. Each element contains the following attributes: + * `console_login` - Indicate whether the CAM role can be login or not. + * `create_time` - The create time of the CAM role. + * `description` - Description of CAM role. + * `document` - Policy document of CAM role. + * `name` - Name of CAM role. + * `role_id` - Id of CAM role. + * `update_time` - The last update time of the CAM role. + + diff --git a/website/docs/d/cam_saml_providers.html.markdown b/website/docs/d/cam_saml_providers.html.markdown new file mode 100644 index 0000000000..90e838e751 --- /dev/null +++ b/website/docs/d/cam_saml_providers.html.markdown @@ -0,0 +1,39 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_saml_providers" +sidebar_current: "docs-tencentcloud-datasource-cam_saml_providers" +description: |- + Use this data source to query detailed information of CAM SAML providers +--- + +# tencentcloud_cam_saml_providers + +Use this data source to query detailed information of CAM SAML providers + +## Example Usage + +```hcl +data "tencentcloud_cam_saml_providers" "foo" { + name = "cam-test-provider" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `description` - (Optional) The description of the CAM SAML provider . +* `name` - (Optional) Name of the CAM SAML provider to be queried. +* `result_output_file` - (Optional) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `provider_list` - A list of CAM SAML providers. Each element contains the following attributes: + * `create_time` - Create time of the CAM SAML provider. + * `description` - Description of CAM SAML provider. + * `modify_time` - The last modify time of the CAM SAML provider. + * `name` - Name of CAM SAML provider. + + diff --git a/website/docs/d/cam_user_policy_attachments.html.markdown b/website/docs/d/cam_user_policy_attachments.html.markdown new file mode 100644 index 0000000000..1b341b0736 --- /dev/null +++ b/website/docs/d/cam_user_policy_attachments.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_user_policy_attachments" +sidebar_current: "docs-tencentcloud-datasource-cam_user_policy_attachments" +description: |- + Use this data source to query detailed information of CAM user policy attachments +--- + +# tencentcloud_cam_user_policy_attachments + +Use this data source to query detailed information of CAM user policy attachments + +## Example Usage + +```hcl +data "tencentcloud_cam_user_policy_attachments" "foo" { + user_id = "cam-test" + policy_id = "215153266" + policy_type = "QCS" + create_mode = 1 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `user_id` - (Required) Id of the attached CAM user to be queried. +* `create_mode` - (Optional) Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. +* `policy_id` - (Optional) Id of CAM policy to be queried. +* `policy_type` - (Optional) Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. +* `result_output_file` - (Optional) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `user_policy_attachment_list` - A list of CAM user policy attachments. Each element contains the following attributes: + * `create_mode` - Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. + * `create_time` - The create time of the CAM user policy attachment. + * `policy_id` - Name of CAM user. + * `policy_name` - The name of the policy. + * `policy_type` - Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. + * `user_id` - Id of CAM user. + + diff --git a/website/docs/d/cam_users.html.markdown b/website/docs/d/cam_users.html.markdown new file mode 100644 index 0000000000..8bed012936 --- /dev/null +++ b/website/docs/d/cam_users.html.markdown @@ -0,0 +1,55 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_users" +sidebar_current: "docs-tencentcloud-datasource-cam_users" +description: |- + Use this data source to query detailed information of CAM users +--- + +# tencentcloud_cam_users + +Use this data source to query detailed information of CAM users + +## Example Usage + +```hcl +data "tencentcloud_cam_users" "foo" { + name = "cam-user-test" + remark = "test" + console_login = true + email = "1245@qq.com" + uin = 151252 + country_code = "86" + phone_num = 1215151516 + uid = 5043021 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `console_login` - (Optional) Indicate whether the user can login in. +* `country_code` - (Optional) Country code of the CAM user to be queried. +* `email` - (Optional) Email of the CAM user to be queried. +* `name` - (Optional) Name of CAM user to be queried. +* `phone_num` - (Optional) Phone num of the CAM user to be queried. +* `remark` - (Optional) Remark of the CAM user to be queried. +* `result_output_file` - (Optional) Used to save results. +* `uid` - (Optional) Uid of the CAM user to be queried. +* `uin` - (Optional) Uin of the CAM user to be queried. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `user_list` - A list of CAM users. Each element contains the following attributes: + * `country_code` - Country code of the CAM user. + * `email` - Email of the CAM user. + * `name` - Name of CAM user. + * `phone_num` - Phone num of the CAM user. + * `remark` - Remark of the CAM user. + * `uid` - Uid of the CAM user. + * `uin` - Uin of the CAM user. + + diff --git a/website/docs/r/cam_group.html.markdown b/website/docs/r/cam_group.html.markdown new file mode 100644 index 0000000000..a7342a3fe0 --- /dev/null +++ b/website/docs/r/cam_group.html.markdown @@ -0,0 +1,43 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_group" +sidebar_current: "docs-tencentcloud-resource-cam_group" +description: |- + Provides a resource to create a CAM group. +--- + +# tencentcloud_cam_group + +Provides a resource to create a CAM group. + +## Example Usage + +```hcl +resource "tencentcloud_cam_group" "foo" { + name = "cam-group-test" + remark = "test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Name of cam group. +* `remark` - (Optional) Description of the cam group. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_time` - Create time of the CAM group. + + +## Import + +CAM group can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_group.foo 90496 +``` + diff --git a/website/docs/r/cam_group_membership.html.markdown b/website/docs/r/cam_group_membership.html.markdown new file mode 100644 index 0000000000..d2ff6675ec --- /dev/null +++ b/website/docs/r/cam_group_membership.html.markdown @@ -0,0 +1,37 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_group_membership" +sidebar_current: "docs-tencentcloud-resource-cam_group_membership" +description: |- + Provides a resource to create a CAM group membership. +--- + +# tencentcloud_cam_group_membership + +Provides a resource to create a CAM group membership. + +## Example Usage + +```hcl +resource "tencentcloud_cam_group_membership" "foo" { + group_id = "12515263" + user_ids = ["cam-test", "cam-test2"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `group_id` - (Required) Id of cam group. +* `user_ids` - (Required) Id set of the cam group members. + + +## Import + +CAM group membership can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_group_membership.foo 12515263 +``` + diff --git a/website/docs/r/cam_group_policy_attachment.html.markdown b/website/docs/r/cam_group_policy_attachment.html.markdown new file mode 100644 index 0000000000..ba15b937a4 --- /dev/null +++ b/website/docs/r/cam_group_policy_attachment.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_group_policy_attachment" +sidebar_current: "docs-tencentcloud-resource-cam_group_policy_attachment" +description: |- + Provides a resource to create a CAM group policy attachment. +--- + +# tencentcloud_cam_group_policy_attachment + +Provides a resource to create a CAM group policy attachment. + +## Example Usage + +```hcl +resource "tencentcloud_cam_group_attachment" "foo" { + group_id = "12515263" + policy_id = "26800353" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `group_id` - (Required, ForceNew) I of the attached cam group. +* `policy_id` - (Required, ForceNew) Id of the policy. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_mode` - Mode of Creation of the CAM group policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. +* `create_time` - Create time of the CAM group policy attachment. +* `policy_name` - Name of the policy. +* `policy_type` - Type of the policy strategy. 'Group' means customer strategy and 'QCS' means preset strategy. + + +## Import + +CAM group policy attachment can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_group_attachment.foo 12515263#26800353 +``` + diff --git a/website/docs/r/cam_policy.html.markdown b/website/docs/r/cam_policy.html.markdown new file mode 100644 index 0000000000..3dc8cb5eb1 --- /dev/null +++ b/website/docs/r/cam_policy.html.markdown @@ -0,0 +1,47 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_policy" +sidebar_current: "docs-tencentcloud-resource-cam_policy" +description: |- + Provides a resource to create a CAM policy. +--- + +# tencentcloud_cam_policy + +Provides a resource to create a CAM policy. + +## Example Usage + +```hcl +resource "tencentcloud_cam_policy" "foo" { + name = "cam-policy-test" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":[\"name/sts:AssumeRole\"],\"effect\":\"allow\",\"resource\":[\"*\"]}]}" + description = "test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `document` - (Required) Document of the CAM policy. The syntax refers to https://intl.cloud.tencent.com/document/product/598/10604. There are some notes when using this para in terraform: 1. The elements in JSON claimed supporting two types as `string` and `array` only support type `array`; 2. Terraform does not support the `root` syntax, when it appears, it must be replaced with the uin it stands for. +* `name` - (Required, ForceNew) Name of CAM policy. +* `description` - (Optional) Description of the CAM policy. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_time` - Create time of the CAM policy. +* `type` - Type of the policy strategy. 1 means customer strategy and 2 means preset strategy. +* `update_time` - The last update time of the CAM policy. + + +## Import + +CAM policy can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_policy.foo 26655801 +``` + diff --git a/website/docs/r/cam_role.html.markdown b/website/docs/r/cam_role.html.markdown new file mode 100644 index 0000000000..8f2592b70d --- /dev/null +++ b/website/docs/r/cam_role.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_role" +sidebar_current: "docs-tencentcloud-resource-cam_role" +description: |- + Provides a resource to create a CAM role. +--- + +# tencentcloud_cam_role + +Provides a resource to create a CAM role. + +## Example Usage + +```hcl +resource "tencentcloud_cam_role" "foo" { + name = "cam-role-test" + document = "{\"version\":\"2.0\",\"statement\":[{\"action\":\"name/sts:AssumeRole\",\"effect\":\"allow\",\"principal\":{\"qcs\":\"qcs::cam::uin/3374997817:uin/3374997817\"}}]}" + description = "test" + console_login = true +} +``` + +## Argument Reference + +The following arguments are supported: + +* `document` - (Required) Document of the CAM role. The syntax refers to https://intl.cloud.tencent.com/document/product/598/10604. There are some notes when using this para in terraform: 1. The elements in json claimed supporting two types as `string` and `array` only support type `array`; 2. Terraform does not support the `root` syntax, when appears, it must be replaced with the uin it stands for. +* `name` - (Required, ForceNew) Name of CAM role. +* `console_login` - (Optional, ForceNew) Indicade whether the CAM role can login or not. +* `description` - (Optional) Description of the CAM role. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_time` - Create time of the CAM role. +* `update_time` - The last update time of the CAM role. + + +## Import + +CAM role can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_role.foo 4611686018427733635 +``` + diff --git a/website/docs/r/cam_role_policy_attachment.html.markdown b/website/docs/r/cam_role_policy_attachment.html.markdown new file mode 100644 index 0000000000..b4b3539698 --- /dev/null +++ b/website/docs/r/cam_role_policy_attachment.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_role_policy_attachment" +sidebar_current: "docs-tencentcloud-resource-cam_role_policy_attachment" +description: |- + Provides a resource to create a CAM role policy attachment. +--- + +# tencentcloud_cam_role_policy_attachment + +Provides a resource to create a CAM role policy attachment. + +## Example Usage + +```hcl +resource "tencentcloud_cam_role_attachment" "foo" { + group_id = "4611686018427922725" + policy_id = "26800353" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `policy_id` - (Required, ForceNew) Id of the policy. +* `role_id` - (Required, ForceNew) Id of the attached cam role. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_mode` - Mode of Creation of the CAM role policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. +* `create_time` - The create time of the CAM role policy attachment. +* `policy_name` - The name of the policy. +* `policy_type` - Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. + + +## Import + +CAM role policy attachment can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_role_attachment.foo 4611686018427922725#26800353 +``` + diff --git a/website/docs/r/cam_saml_provider.html.markdown b/website/docs/r/cam_saml_provider.html.markdown new file mode 100644 index 0000000000..93ab0045cb --- /dev/null +++ b/website/docs/r/cam_saml_provider.html.markdown @@ -0,0 +1,47 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_saml_provider" +sidebar_current: "docs-tencentcloud-resource-cam_saml_provider" +description: |- + Provides a resource to create a CAM SAML provider. +--- + +# tencentcloud_cam_saml_provider + +Provides a resource to create a CAM SAML provider. + +## Example Usage + +```hcl +resource "tencentcloud_cam_saml_provider" "saml_provider_basic" { + name = "cam-saml-provider-test" + meta_data = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48bWQ6RW50aXR5RGVzY3JpcHRvciBlbnRpdHlJRD0iaHR0cDovL3d3dy5va3RhLmNvbS9leGsxa3F4bWNqUW1HQURNeTM1NyIgeG1sbnM6bWQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDptZXRhZGF0YSI+PG1kOklEUFNTT0Rlc2NyaXB0b3IgV2FudEF1dGhuUmVxdWVzdHNTaWduZWQ9ImZhbHNlIiBwcm90b2NvbFN1cHBvcnRFbnVtZXJhdGlvbj0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIj48bWQ6S2V5RGVzY3JpcHRvciB1c2U9InNpZ25pbmciPjxkczpLZXlJbmZvIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj48ZHM6WDUwOURhdGE+PGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlEb0RDQ0FvaWdBd0lCQWdJR0FXM0lTcExvTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdRTVFzd0NRWURWUVFHRXdKVlV6RVRNQkVHDQpBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeVlXNWphWE5qYnpFTk1Bc0dBMVVFQ2d3RVQydDBZVEVVDQpNQklHQTFVRUN3d0xVMU5QVUhKdmRtbGtaWEl4RVRBUEJnTlZCQU1NQ0dsa2VIVmxkblJoTVJ3d0dnWUpLb1pJaHZjTkFRa0JGZzFwDQpibVp2UUc5cmRHRXVZMjl0TUI0WERURTVNVEF4TkRBek1qSXhNMW9YRFRJNU1UQXhOREF6TWpNeE0xb3dnWkF4Q3pBSkJnTlZCQVlUDQpBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SWXdGQVlEVlFRSERBMVRZVzRnUm5KaGJtTnBjMk52TVEwd0N3WURWUVFLDQpEQVJQYTNSaE1SUXdFZ1lEVlFRTERBdFRVMDlRY205MmFXUmxjakVSTUE4R0ExVUVBd3dJYVdSNGRXVjJkR0V4SERBYUJna3Foa2lHDQo5dzBCQ1FFV0RXbHVabTlBYjJ0MFlTNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2g4b3dqDQpZK2dQSUM3blQvNTduLzdmeXJzcDlHMXdxa2UxdXhjMHVrTndnQXozOVNpelY3QVhLMWRReTFLaThXWjJJMzFEczJkT0FNQ1FKR2pWDQpUWWNNbnA3KzhqUzNLdmxNUkRJamk5cmxuUi9vcnBvMll1RHVWby9jVzdidlRIS2h2REo1QWZRaWxzYlNPTXdUOWM2TVlYZGhBNVBwDQpzelFsK1UrdHJmcXUrdUorSER4SVQxdlhWaVI5YlY2SUFRSzZpbWZoc2wxWmVSUytjbVFVNEpjQWlYT0xtTnFVVWM2UkpxUzhrMW1mDQpBLzhmb2VyMGc3SG4xZDVXclpCc2gyUlR2Vzh1ZVdadHQ3dmh4QTlGdE5kSVlEcXJ0eElmMlZXcXhrSHM3WFZDSm5wTnJITVovT1BRDQpGY21YSGVxNlJJMlB3Q1RlOW8zZHZpM0hqeXBaOEl4dkFnTUJBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUFHaHk1bG9nbGtTDQoyVHg2YS90MnF5VEx0YVV5cEwrNGhySGJoMVAweVVMc0NrSnFsM2wrWG9VZDZCY2FJaFNSVGFPQk95ODViL0UzelJ4K3JzQXJwTjVVDQp5ZThuUEM4a05PYW5vTk9wWnZvYmhpTzFlMFIvYmxEcnRBL0o5UlBwMWtmdlhmS2NSTTU3TlRCWXppTURlbnFQUTRFOWN1U2lGdFFxDQpJYmpIbThaM1B1YXgwRitldkZ3U1pJMDNCWXNISGw1d1EraEJBS3hTdTJINEZRdU93Zmpnb2EveEN6Z1NKYjJ2UXdEc1MxMk9mSkNiDQpSRm1ZL1VYZXQramFhdEVORktLZStZSUJpU0J2WG1adTN0MHN5NDZTNzlPVzBacXJ0NUh2bElsT2lpTFpaN1FZamxjM1kxeG1LZ1luDQpXM2M2WGZkdmhGWHo0ZDdkbWYvTUdpNGY0enM9PC9kczpYNTA5Q2VydGlmaWNhdGU+PC9kczpYNTA5RGF0YT48L2RzOktleUluZm8+PC9tZDpLZXlEZXNjcmlwdG9yPjxtZDpOYW1lSURGb3JtYXQ+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQ8L21kOk5hbWVJREZvcm1hdD48bWQ6TmFtZUlERm9ybWF0PnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzczwvbWQ6TmFtZUlERm9ybWF0PjxtZDpTaW5nbGVTaWduT25TZXJ2aWNlIEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLVBPU1QiIExvY2F0aW9uPSJodHRwczovL2lkeHVldnRhLm9rdGEuY29tL2FwcC9pZHh1ZW9yZzYzNzM1OF90ZXN0XzEvZXhrMWtxeG1jalFtR0FETXkzNTcvc3NvL3NhbWwiLz48bWQ6U2luZ2xlU2lnbk9uU2VydmljZSBCaW5kaW5nPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YmluZGluZ3M6SFRUUC1SZWRpcmVjdCIgTG9jYXRpb249Imh0dHBzOi8vaWR4dWV2dGEub2t0YS5jb20vYXBwL2lkeHVlb3JnNjM3MzU4X3Rlc3RfMS9leGsxa3F4bWNqUW1HQURNeTM1Ny9zc28vc2FtbCIvPjwvbWQ6SURQU1NPRGVzY3JpcHRvcj48L21kOkVudGl0eURlc2NyaXB0b3I+" + description = "test" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `description` - (Required) The description of the CAM SAML provider. +* `meta_data` - (Required) The meta data document of the CAM SAML provider. +* `name` - (Required) Name of CAM SAML provider. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_time` - The create time of the CAM SAML provider. +* `provider_arn` - The arn of the CAM SAML provider. +* `update_time` - The last update time of the CAM SAML provider. + + +## Import + +CAM SAML provider can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_saml_provider.foo cam-SAML-provider-test +``` + diff --git a/website/docs/r/cam_user.html.markdown b/website/docs/r/cam_user.html.markdown new file mode 100644 index 0000000000..bb72783b56 --- /dev/null +++ b/website/docs/r/cam_user.html.markdown @@ -0,0 +1,59 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_user" +sidebar_current: "docs-tencentcloud-resource-cam_user" +description: |- + Provides a resource to create a CAM user. +--- + +# tencentcloud_cam_user + +Provides a resource to create a CAM user. + +## Example Usage + +```hcl +resource "tencentcloud_cam_user" "foo" { + name = "cam-user-test" + remark = "test" + console_login = true + use_api = true + need_reset_password = true + password = "Gail@1234" + phone_num = "13631555963" + country_code = "86" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required, ForceNew) Name of CAM user. +* `console_login` - (Optional) Indicade whether the CAM user can login or not. +* `country_code` - (Optional) Country code of the phone num, like '86' +* `email` - (Optional) Email of the CAM user. +* `need_reset_password` - (Optional) Indicate whether the CAM user will reset the password the next time he/her logs in. +* `password` - (Optional) The password of the CAM user. The password should be set with 8 characters or more and contains uppercase small letters, numbers, and special characters. Only valid when console_login set true. If not set and the value of console_login is true, a random password is automatically generated. +* `phone_num` - (Optional) Phone num of the CAM user. +* `remark` - (Optional) Remark of the CAM user. +* `use_api` - (Optional) Indicate whether to generate a secret key or not. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `secret_id` - Secret Id of the CAM user. +* `secret_key` - Secret key of the CAM user. +* `uid` - Id of the CAM user +* `uin` - Uin of the CAM User. + + +## Import + +CAM user can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_user.foo cam-user-test +``` + diff --git a/website/docs/r/cam_user_policy_attachment.html.markdown b/website/docs/r/cam_user_policy_attachment.html.markdown new file mode 100644 index 0000000000..9e653c8073 --- /dev/null +++ b/website/docs/r/cam_user_policy_attachment.html.markdown @@ -0,0 +1,46 @@ +--- +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_cam_user_policy_attachment" +sidebar_current: "docs-tencentcloud-resource-cam_user_policy_attachment" +description: |- + Provides a resource to create a CAM user policy attachment. +--- + +# tencentcloud_cam_user_policy_attachment + +Provides a resource to create a CAM user policy attachment. + +## Example Usage + +```hcl +resource "tencentcloud_cam_user_policy_attachment" "foo" { + user_id = "cam-test" + policy_id = "26800353" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `policy_id` - (Required, ForceNew) Id of the policy. +* `user_id` - (Required, ForceNew) Id of the attached cam user. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `create_mode` - Mode of Creation of the CAM user policy attachment. 1 means the cam policy attachment is created by production, and the others indicate syntax strategy ways. +* `create_time` - Create time of the CAM user policy attachment. +* `policy_name` - Name of the policy. +* `policy_type` - Type of the policy strategy. 'User' means customer strategy and 'QCS' means preset strategy. + + +## Import + +CAM user policy attachment can be imported using the id, e.g. + +``` +$ terraform import tencentcloud_cam_user_attachment.foo cam-test#26800353 +``` +