diff --git a/alicloud/provider.go b/alicloud/provider.go index 48f2b51d584f..c46c115195a8 100644 --- a/alicloud/provider.go +++ b/alicloud/provider.go @@ -887,6 +887,9 @@ func Provider() terraform.ResourceProvider { "alicloud_vpc_ipam_ipams": dataSourceAliCloudVpcIpamIpams(), }, ResourcesMap: map[string]*schema.Resource{ + "alicloud_max_compute_quota_schedule": resourceAliCloudMaxComputeQuotaSchedule(), + "alicloud_max_compute_role": resourceAliCloudMaxComputeRole(), + "alicloud_max_compute_quota_plan": resourceAliCloudMaxComputeQuotaPlan(), "alicloud_vpc_ipam_service": resourceAliCloudVpcIpamService(), "alicloud_alb_load_balancer_zone_shifted_attachment": resourceAliCloudAlbLoadBalancerZoneShiftedAttachment(), "alicloud_alb_load_balancer_access_log_config_attachment": resourceAliCloudAlbLoadBalancerAccessLogConfigAttachment(), diff --git a/alicloud/resource_alicloud_max_compute_quota_plan.go b/alicloud/resource_alicloud_max_compute_quota_plan.go new file mode 100644 index 000000000000..cc016af33447 --- /dev/null +++ b/alicloud/resource_alicloud_max_compute_quota_plan.go @@ -0,0 +1,472 @@ +// Package alicloud. This file is generated automatically. Please do not modify it manually, thank you! +package alicloud + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/PaesslerAG/jsonpath" + util "github.com/alibabacloud-go/tea-utils/service" + "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceAliCloudMaxComputeQuotaPlan() *schema.Resource { + return &schema.Resource{ + Create: resourceAliCloudMaxComputeQuotaPlanCreate, + Read: resourceAliCloudMaxComputeQuotaPlanRead, + Update: resourceAliCloudMaxComputeQuotaPlanUpdate, + Delete: resourceAliCloudMaxComputeQuotaPlanDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "is_effective": { + Type: schema.TypeBool, + Optional: true, + }, + "nickname": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "plan_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "quota": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sub_quota_info_list": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "parameter": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "elastic_reserved_cu": { + Type: schema.TypeInt, + Required: true, + }, + "min_cu": { + Type: schema.TypeInt, + Required: true, + }, + "max_cu": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "nick_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + }, + "parameter": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "elastic_reserved_cu": { + Type: schema.TypeInt, + Required: true, + }, + "min_cu": { + Type: schema.TypeInt, + Computed: true, + }, + "max_cu": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func resourceAliCloudMaxComputeQuotaPlanCreate(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*connectivity.AliyunClient) + + nickname := d.Get("nickname") + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaPlan", nickname) + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]*string) + body := make(map[string]interface{}) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + if v, ok := d.GetOk("plan_name"); ok { + request["name"] = v + } + + objectDataLocalMap := make(map[string]interface{}) + + if v := d.Get("quota"); !IsNil(v) { + parameter := make(map[string]interface{}) + elasticReservedCu, _ := jsonpath.Get("$[0].parameter[0].elastic_reserved_cu", v) + if elasticReservedCu != nil && elasticReservedCu != "" { + parameter["elasticReservedCU"] = elasticReservedCu + } + + objectDataLocalMap["parameter"] = parameter + if v, ok := d.GetOk("quota"); ok { + localData, err := jsonpath.Get("$[0].sub_quota_info_list", v) + if err != nil { + localData = make([]interface{}, 0) + } + localMaps := make([]interface{}, 0) + for _, dataLoop := range localData.(*schema.Set).List() { + dataLoopTmp := make(map[string]interface{}) + if dataLoop != nil { + dataLoopTmp = dataLoop.(map[string]interface{}) + } + dataLoopMap := make(map[string]interface{}) + localData1 := make(map[string]interface{}) + minCu, _ := jsonpath.Get("$[0].min_cu", dataLoopTmp["parameter"]) + if minCu != nil && minCu != "" { + localData1["minCU"] = minCu + } + maxCu, _ := jsonpath.Get("$[0].max_cu", dataLoopTmp["parameter"]) + if maxCu != nil && maxCu != "" { + localData1["maxCU"] = maxCu + } + elasticReservedCu1, _ := jsonpath.Get("$[0].elastic_reserved_cu", dataLoopTmp["parameter"]) + if elasticReservedCu1 != nil && elasticReservedCu1 != "" { + localData1["elasticReservedCU"] = elasticReservedCu1 + } + dataLoopMap["parameter"] = localData1 + dataLoopMap["nickName"] = dataLoopTmp["nick_name"] + localMaps = append(localMaps, dataLoopMap) + } + objectDataLocalMap["subQuotaInfoList"] = localMaps + } + + request["quota"] = objectDataLocalMap + } + + body = request + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("POST"), StringPointer("AK"), StringPointer(action), query, nil, body, &runtime) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, "alicloud_max_compute_quota_plan", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprintf("%v:%v", nickname, request["name"])) + + return resourceAliCloudMaxComputeQuotaPlanUpdate(d, meta) +} + +func resourceAliCloudMaxComputeQuotaPlanRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + maxComputeServiceV2 := MaxComputeServiceV2{client} + + objectRaw, err := maxComputeServiceV2.DescribeMaxComputeQuotaPlan(d.Id()) + if err != nil { + if !d.IsNewResource() && NotFoundError(err) { + log.Printf("[DEBUG] Resource alicloud_max_compute_quota_plan DescribeMaxComputeQuotaPlan Failed!!! %s", err) + d.SetId("") + return nil + } + return WrapError(err) + } + + if objectRaw["isEffective"] != nil { + d.Set("is_effective", objectRaw["isEffective"]) + } + if objectRaw["name"] != nil { + d.Set("plan_name", objectRaw["name"]) + } + + quotaMaps := make([]map[string]interface{}, 0) + quotaMap := make(map[string]interface{}) + quota1Raw := make(map[string]interface{}) + if objectRaw["quota"] != nil { + quota1Raw = objectRaw["quota"].(map[string]interface{}) + } + if len(quota1Raw) > 0 { + + parameterMaps := make([]map[string]interface{}, 0) + parameterMap := make(map[string]interface{}) + parameter2Raw := make(map[string]interface{}) + if quota1Raw["parameter"] != nil { + parameter2Raw = quota1Raw["parameter"].(map[string]interface{}) + } + if len(parameter2Raw) > 0 { + parameterMap["elastic_reserved_cu"] = parameter2Raw["elasticReservedCU"] + parameterMap["max_cu"] = parameter2Raw["maxCU"] + parameterMap["min_cu"] = parameter2Raw["minCU"] + + parameterMaps = append(parameterMaps, parameterMap) + } + quotaMap["parameter"] = parameterMaps + subQuotaInfoList1Raw := quota1Raw["subQuotaInfoList"] + subQuotaInfoListMaps := make([]map[string]interface{}, 0) + if subQuotaInfoList1Raw != nil { + for _, subQuotaInfoListChild1Raw := range subQuotaInfoList1Raw.([]interface{}) { + subQuotaInfoListMap := make(map[string]interface{}) + subQuotaInfoListChild1Raw := subQuotaInfoListChild1Raw.(map[string]interface{}) + subQuotaInfoListMap["nick_name"] = subQuotaInfoListChild1Raw["nickName"] + + parameterMaps := make([]map[string]interface{}, 0) + parameterMap := make(map[string]interface{}) + parameter3Raw := make(map[string]interface{}) + if subQuotaInfoListChild1Raw["parameter"] != nil { + parameter3Raw = subQuotaInfoListChild1Raw["parameter"].(map[string]interface{}) + } + if len(parameter3Raw) > 0 { + parameterMap["elastic_reserved_cu"] = parameter3Raw["elasticReservedCU"] + parameterMap["max_cu"] = parameter3Raw["maxCU"] + parameterMap["min_cu"] = parameter3Raw["minCU"] + + parameterMaps = append(parameterMaps, parameterMap) + } + subQuotaInfoListMap["parameter"] = parameterMaps + subQuotaInfoListMaps = append(subQuotaInfoListMaps, subQuotaInfoListMap) + } + } + quotaMap["sub_quota_info_list"] = subQuotaInfoListMaps + quotaMaps = append(quotaMaps, quotaMap) + } + if objectRaw["quota"] != nil { + if err := d.Set("quota", quotaMaps); err != nil { + return err + } + } + + parts := strings.Split(d.Id(), ":") + d.Set("nickname", parts[0]) + + return nil +} + +func resourceAliCloudMaxComputeQuotaPlanUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + var request map[string]interface{} + var response map[string]interface{} + var query map[string]*string + var body map[string]interface{} + update := false + + if d.HasChange("is_effective") { + maxComputeServiceV2 := MaxComputeServiceV2{client} + object, err := maxComputeServiceV2.DescribeMaxComputeQuotaPlan(d.Id()) + if err != nil { + return WrapError(err) + } + + target := d.Get("is_effective").(bool) + if object["isEffective"].(bool) != target { + if target == true { + parts := strings.Split(d.Id(), ":") + planName := parts[1] + nickname := parts[0] + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaPlan/%s/apply", nickname, planName) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + body = make(map[string]interface{}) + + body = request + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("PUT"), StringPointer("AK"), StringPointer(action), query, nil, body, &runtime) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + + } + } + } + + parts := strings.Split(d.Id(), ":") + nickname := parts[0] + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaPlan", nickname) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + body = make(map[string]interface{}) + request["name"] = parts[1] + + if d.HasChange("quota") { + update = true + } + objectDataLocalMap := make(map[string]interface{}) + + if v := d.Get("quota"); v != nil { + parameter := make(map[string]interface{}) + elasticReservedCu, _ := jsonpath.Get("$[0].parameter[0].elastic_reserved_cu", v) + if elasticReservedCu != nil && (d.HasChange("quota.0.parameter.0.elastic_reserved_cu") || elasticReservedCu != "") { + parameter["elasticReservedCU"] = elasticReservedCu + } + + objectDataLocalMap["parameter"] = parameter + if v, ok := d.GetOk("quota"); ok { + localData, err := jsonpath.Get("$[0].sub_quota_info_list", v) + if err != nil { + localData = make([]interface{}, 0) + } + localMaps := make([]interface{}, 0) + for _, dataLoop := range localData.(*schema.Set).List() { + dataLoopTmp := make(map[string]interface{}) + if dataLoop != nil { + dataLoopTmp = dataLoop.(map[string]interface{}) + } + dataLoopMap := make(map[string]interface{}) + if !IsNil(dataLoopTmp["parameter"]) { + localData1 := make(map[string]interface{}) + elasticReservedCu1, _ := jsonpath.Get("$[0].elastic_reserved_cu", dataLoopTmp["parameter"]) + if elasticReservedCu1 != nil && elasticReservedCu1 != "" { + localData1["elasticReservedCU"] = elasticReservedCu1 + } + maxCu, _ := jsonpath.Get("$[0].max_cu", dataLoopTmp["parameter"]) + if maxCu != nil && maxCu != "" { + localData1["maxCU"] = maxCu + } + minCu, _ := jsonpath.Get("$[0].min_cu", dataLoopTmp["parameter"]) + if minCu != nil && minCu != "" { + localData1["minCU"] = minCu + } + dataLoopMap["parameter"] = localData1 + } + dataLoopMap["nickName"] = dataLoopTmp["nick_name"] + localMaps = append(localMaps, dataLoopMap) + } + objectDataLocalMap["subQuotaInfoList"] = localMaps + } + + request["quota"] = objectDataLocalMap + } + + body = request + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("PUT"), StringPointer("AK"), StringPointer(action), query, nil, body, &runtime) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + } + + return resourceAliCloudMaxComputeQuotaPlanRead(d, meta) +} + +func resourceAliCloudMaxComputeQuotaPlanDelete(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*connectivity.AliyunClient) + parts := strings.Split(d.Id(), ":") + planName := parts[1] + nickname := parts[0] + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaPlan/%s", nickname, planName) + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]*string) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("DELETE"), StringPointer("AK"), StringPointer(action), query, nil, nil, &runtime) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + + if err != nil { + if NotFoundError(err) { + return nil + } + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + + return nil +} diff --git a/alicloud/resource_alicloud_max_compute_quota_plan_test.go b/alicloud/resource_alicloud_max_compute_quota_plan_test.go new file mode 100644 index 000000000000..af8ca1254623 --- /dev/null +++ b/alicloud/resource_alicloud_max_compute_quota_plan_test.go @@ -0,0 +1,594 @@ +package alicloud + +import ( + "fmt" + "testing" + + "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +// Test MaxCompute QuotaPlan. >>> Resource test cases, automatically generated. +// Case QuotaPlan_terraform测试 9566 +func TestAccAliCloudMaxComputeQuotaPlan_basic9566(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_max_compute_quota_plan.default" + ra := resourceAttrInit(resourceId, AlicloudMaxComputeQuotaPlanMap9566) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &MaxComputeServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeMaxComputeQuotaPlan") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tf-testacc%smaxcomputequotaplan%d", defaultRegionToTest, rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudMaxComputeQuotaPlanBasicDependence9566) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheckWithRegions(t, true, []connectivity.Region{"cn-hangzhou"}) + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "quota": []map[string]interface{}{ + { + "parameter": []map[string]interface{}{ + { + "elastic_reserved_cu": "${var.elastic_reserved_cu}", + }, + }, + "sub_quota_info_list": []map[string]interface{}{ + { + "nick_name": "sub_quota", + "parameter": []map[string]interface{}{ + { + "min_cu": "0", + "max_cu": "20", + "elastic_reserved_cu": "${var.elastic_reserved_cu}", + }, + }, + }, + { + "nick_name": "os_terrform", + "parameter": []map[string]interface{}{ + { + "min_cu": "50", + "max_cu": "50", + "elastic_reserved_cu": "0", + }, + }, + }, + }, + }, + }, + "plan_name": "quota_plan", + "nickname": "os_terrform_p", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "plan_name": CHECKSET, + "nickname": CHECKSET, + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "quota": []map[string]interface{}{ + { + "parameter": []map[string]interface{}{ + { + "elastic_reserved_cu": "${var.update_elastic_reserved_cu}", + }, + }, + "sub_quota_info_list": []map[string]interface{}{ + { + "nick_name": "sub_quota", + "parameter": []map[string]interface{}{ + { + "min_cu": "30", + "max_cu": "40", + "elastic_reserved_cu": "0", + }, + }, + }, + { + "nick_name": "os_terrform", + "parameter": []map[string]interface{}{ + { + "min_cu": "20", + "max_cu": "40", + "elastic_reserved_cu": "${var.update_elastic_reserved_cu}", + }, + }, + }, + }, + }, + }, + "is_effective": "false", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "is_effective": "false", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +var AlicloudMaxComputeQuotaPlanMap9566 = map[string]string{} + +func AlicloudMaxComputeQuotaPlanBasicDependence9566(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "elastic_reserved_cu" { + default = "50" +} + +variable "sub1" { + default = "sub1" +} + +variable "sub_max_cu" { + default = "35" +} + +variable "update_elastic_reserved_cu" { + default = "0" +} + +variable "plan_name" { + default = "TFPlan1737081504" +} + +variable "part_name" { + default = "TFTest" +} + + +`, name) +} + +// Case QuotaPlanApply_terraform测试(update) 9854 +func TestAccAliCloudMaxComputeQuotaPlan_basic9854(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_max_compute_quota_plan.default" + ra := resourceAttrInit(resourceId, AlicloudMaxComputeQuotaPlanMap9854) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &MaxComputeServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeMaxComputeQuotaPlan") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tf-testacc%smaxcomputequotaplan%d", defaultRegionToTest, rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudMaxComputeQuotaPlanBasicDependence9854) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheckWithRegions(t, true, []connectivity.Region{"cn-hangzhou"}) + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "quota": []map[string]interface{}{ + { + "parameter": []map[string]interface{}{ + { + "elastic_reserved_cu": "${var.elastic_reserved_cu}", + }, + }, + "sub_quota_info_list": []map[string]interface{}{ + { + "nick_name": "sub_quota", + "parameter": []map[string]interface{}{ + { + "min_cu": "0", + "max_cu": "37", + "elastic_reserved_cu": "${var.elastic_reserved_cu}", + }, + }, + }, + { + "nick_name": "os_terrform", + "parameter": []map[string]interface{}{ + { + "min_cu": "50", + "max_cu": "50", + "elastic_reserved_cu": "0", + }, + }, + }, + }, + }, + }, + "plan_name": "${var.plan_name}", + "is_effective": "false", + "nickname": "os_terrform_p", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "plan_name": CHECKSET, + "is_effective": "false", + "nickname": CHECKSET, + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "quota": []map[string]interface{}{ + { + "parameter": []map[string]interface{}{ + { + "elastic_reserved_cu": "${var.update_elastic_reserved_cu}", + }, + }, + "sub_quota_info_list": []map[string]interface{}{ + { + "nick_name": "os_terrform", + "parameter": []map[string]interface{}{ + { + "min_cu": "30", + "max_cu": "50", + "elastic_reserved_cu": "0", + }, + }, + }, + { + "nick_name": "sub_quota", + "parameter": []map[string]interface{}{ + { + "min_cu": "20", + "max_cu": "40", + "elastic_reserved_cu": "${var.update_elastic_reserved_cu}", + }, + }, + }, + }, + }, + }, + "is_effective": "true", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "is_effective": "true", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +var AlicloudMaxComputeQuotaPlanMap9854 = map[string]string{} + +func AlicloudMaxComputeQuotaPlanBasicDependence9854(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "elastic_reserved_cu" { + default = 50 +} + +variable "sub1" { + default = "sub1" +} + +variable "sub_max_cu" { + default = "920" +} + +variable "update_elastic_reserved_cu" { + default = 0 +} + +variable "plan_name" { + default = "TFPlan1737081505" +} + +variable "part_name" { + default = "TFTest" +} + + +`, name) +} + +// Case QuotaPlanApply_terraform测试(create) 9853 +func TestAccAliCloudMaxComputeQuotaPlan_basic9853(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_max_compute_quota_plan.default" + ra := resourceAttrInit(resourceId, AlicloudMaxComputeQuotaPlanMap9853) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &MaxComputeServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeMaxComputeQuotaPlan") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tf-testacc%smaxcomputequotaplan%d", defaultRegionToTest, rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudMaxComputeQuotaPlanBasicDependence9853) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheckWithRegions(t, true, []connectivity.Region{"cn-beijing"}) + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "quota": []map[string]interface{}{ + { + "parameter": []map[string]interface{}{ + { + "elastic_reserved_cu": "${var.elastic_reserved_cu}", + }, + }, + "sub_quota_info_list": []map[string]interface{}{ + { + "nick_name": "${var.sub1}", + "parameter": []map[string]interface{}{ + { + "min_cu": "0", + "max_cu": "370", + "elastic_reserved_cu": "${var.elastic_reserved_cu}", + }, + }, + }, + { + "nick_name": "os_${{ref(variable, partName)}}", + "parameter": []map[string]interface{}{ + { + "min_cu": "50", + "max_cu": "50", + "elastic_reserved_cu": "0", + }, + }, + }, + }, + }, + }, + "plan_name": "${var.plan_name}", + "is_effective": "true", + "nickname": "os_${{ref(variable, partName)}}_p", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "plan_name": CHECKSET, + "is_effective": "true", + "nickname": "os_${{ref(variable, partName)}}_p", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +var AlicloudMaxComputeQuotaPlanMap9853 = map[string]string{} + +func AlicloudMaxComputeQuotaPlanBasicDependence9853(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "elastic_reserved_cu" { + default = < 0 { + conditionMap["at"] = condition1Raw["at"] + + conditionMaps = append(conditionMaps, conditionMap) + } + scheduleListMap["condition"] = conditionMaps + scheduleListMaps = append(scheduleListMaps, scheduleListMap) + } + } + if objectRaw["data"] != nil { + if err := d.Set("schedule_list", scheduleListMaps); err != nil { + return err + } + } + + parts := strings.Split(d.Id(), ":") + d.Set("nickname", parts[0]) + d.Set("timezone", parts[1]) + + return nil +} + +func resourceAliCloudMaxComputeQuotaScheduleUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + var request map[string]interface{} + var response map[string]interface{} + var query map[string]*string + var body map[string]interface{} + update := false + + parts := strings.Split(d.Id(), ":") + nickname := parts[0] + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaSchedule", nickname) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + body = make(map[string]interface{}) + query["scheduleTimezone"] = StringPointer(parts[1]) + + if d.HasChange("schedule_list") { + update = true + } + if v, ok := d.GetOk("schedule_list"); ok || d.HasChange("schedule_list") { + bodyMapsArray := make([]interface{}, 0) + for _, dataLoop := range v.(*schema.Set).List() { + dataLoopTmp := dataLoop.(map[string]interface{}) + dataLoopMap := make(map[string]interface{}) + if !IsNil(dataLoopTmp["condition"]) { + localData1 := make(map[string]interface{}) + at1, _ := jsonpath.Get("$[0].at", dataLoopTmp["condition"]) + if at1 != nil && at1 != "" { + localData1["at"] = at1 + } + dataLoopMap["condition"] = localData1 + } + dataLoopMap["plan"] = dataLoopTmp["plan"] + dataLoopMap["type"] = dataLoopTmp["type"] + bodyMapsArray = append(bodyMapsArray, dataLoopMap) + } + request["body"] = bodyMapsArray + } + + body = request + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("PUT"), StringPointer("AK"), StringPointer(action), query, nil, body, &runtime) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + } + + return resourceAliCloudMaxComputeQuotaScheduleRead(d, meta) +} + +func resourceAliCloudMaxComputeQuotaScheduleDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARN] Cannot destroy resource AliCloud Resource Quota Schedule. Terraform will remove this resource from the state file, however resources may remain.") + return nil +} diff --git a/alicloud/resource_alicloud_max_compute_quota_schedule_test.go b/alicloud/resource_alicloud_max_compute_quota_schedule_test.go new file mode 100644 index 000000000000..698dcc98945d --- /dev/null +++ b/alicloud/resource_alicloud_max_compute_quota_schedule_test.go @@ -0,0 +1,269 @@ +package alicloud + +import ( + "fmt" + "testing" + + "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +// Test MaxCompute QuotaSchedule. >>> Resource test cases, automatically generated. +// Case QuotaSchedule_terraform测试 9281 +func TestAccAliCloudMaxComputeQuotaSchedule_basic9281(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_max_compute_quota_schedule.default" + ra := resourceAttrInit(resourceId, AlicloudMaxComputeQuotaScheduleMap9281) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &MaxComputeServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeMaxComputeQuotaSchedule") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tf-testacc%smaxcomputequotaschedule%d", defaultRegionToTest, rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudMaxComputeQuotaScheduleBasicDependence9281) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheckWithRegions(t, true, []connectivity.Region{"cn-hangzhou"}) + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "schedule_list": []map[string]interface{}{ + { + "plan": "${alicloud_max_compute_quota_plan.default.plan_name}", + "condition": []map[string]interface{}{ + { + "at": "00:00", + }, + }, + "type": "daily", + }, + { + "plan": "${alicloud_max_compute_quota_plan.default2.plan_name}", + "condition": []map[string]interface{}{ + { + "at": "01:00", + }, + }, + "type": "daily", + }, + { + "plan": "${alicloud_max_compute_quota_plan.default3.plan_name}", + "condition": []map[string]interface{}{ + { + "at": "02:00", + }, + }, + "type": "daily", + }, + }, + "timezone": "UTC+8", + "nickname": "${var.quota_nick_name}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "schedule_list.#": "3", + "timezone": "UTC+8", + "nickname": CHECKSET, + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "schedule_list": []map[string]interface{}{ + { + "plan": "${alicloud_max_compute_quota_plan.default3.plan_name}", + "condition": []map[string]interface{}{ + { + "at": "00:00", + }, + }, + "type": "daily", + }, + { + "plan": "${alicloud_max_compute_quota_plan.default2.plan_name}", + "condition": []map[string]interface{}{ + { + "at": "08:00", + }, + }, + "type": "daily", + }, + { + "condition": []map[string]interface{}{ + { + "at": "10:00", + }, + }, + "plan": "${alicloud_max_compute_quota_plan.default.plan_name}", + "type": "daily", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "schedule_list.#": "3", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "schedule_list": []map[string]interface{}{ + { + "plan": "${alicloud_max_compute_quota_plan.default2.plan_name}", + "condition": []map[string]interface{}{ + { + "at": "00:00", + }, + }, + "type": "daily", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "schedule_list.#": "1", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "schedule_list": []map[string]interface{}{ + { + "plan": "Default", + "condition": []map[string]interface{}{ + { + "at": "00:00", + }, + }, + "type": "daily", + }, + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "schedule_list.#": "1", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +var AlicloudMaxComputeQuotaScheduleMap9281 = map[string]string{} + +func AlicloudMaxComputeQuotaScheduleBasicDependence9281(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + + +variable "elastic_reserved_cu" { + default = "0" +} + +variable "quota_nick_name" { + default = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_plan" "default" { + quota { + parameter { + elastic_reserved_cu = 50 + } + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "0" + max_cu = "20" + elastic_reserved_cu = "30" + } + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "50" + max_cu = "50" + elastic_reserved_cu = "20" + } + + } + } + + plan_name = "quota_plan1" + nickname = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_plan" "default2" { + quota { + parameter { + elastic_reserved_cu = 50 + } + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "0" + max_cu = "20" + elastic_reserved_cu = "20" + } + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "50" + max_cu = "50" + elastic_reserved_cu = "30" + } + + } + } + + plan_name = "quota_plan2" + nickname = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_plan" "default3" { + quota { + parameter { + elastic_reserved_cu = 50 + } + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "40" + max_cu = "40" + elastic_reserved_cu = "40" + } + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "10" + max_cu = "10" + elastic_reserved_cu = "10" + } + + } + } + + plan_name = "quota_plan3" + nickname = "os_terrform_p" +} + +`, name) +} + +// Test MaxCompute QuotaSchedule. <<< Resource test cases, automatically generated. diff --git a/alicloud/resource_alicloud_max_compute_role.go b/alicloud/resource_alicloud_max_compute_role.go new file mode 100644 index 000000000000..d80088e54e65 --- /dev/null +++ b/alicloud/resource_alicloud_max_compute_role.go @@ -0,0 +1,223 @@ +// Package alicloud. This file is generated automatically. Please do not modify it manually, thank you! +package alicloud + +import ( + "fmt" + "log" + "strings" + "time" + + util "github.com/alibabacloud-go/tea-utils/service" + "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceAliCloudMaxComputeRole() *schema.Resource { + return &schema.Resource{ + Create: resourceAliCloudMaxComputeRoleCreate, + Read: resourceAliCloudMaxComputeRoleRead, + Update: resourceAliCloudMaxComputeRoleUpdate, + Delete: resourceAliCloudMaxComputeRoleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "policy": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.ValidateJsonString, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + equal, _ := compareJsonTemplateAreEquivalent(old, new) + return equal + }, + }, + "project_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "role_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: StringInSlice([]string{"admin", "resource"}, false), + }, + }, + } +} + +func resourceAliCloudMaxComputeRoleCreate(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*connectivity.AliyunClient) + + projectName := d.Get("project_name") + action := fmt.Sprintf("/api/v1/projects/%s/roles", projectName) + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]*string) + body := make(map[string]interface{}) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + if v, ok := d.GetOk("role_name"); ok { + request["name"] = v + } + + request["type"] = d.Get("type") + body = request + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("POST"), StringPointer("AK"), StringPointer(action), query, nil, body, &runtime) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, "alicloud_max_compute_role", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprintf("%v:%v", projectName, request["name"])) + + return resourceAliCloudMaxComputeRoleUpdate(d, meta) +} + +func resourceAliCloudMaxComputeRoleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + maxComputeServiceV2 := MaxComputeServiceV2{client} + + objectRaw, err := maxComputeServiceV2.DescribeMaxComputeRole(d.Id()) + if err != nil { + if !d.IsNewResource() && NotFoundError(err) { + log.Printf("[DEBUG] Resource alicloud_max_compute_role DescribeMaxComputeRole Failed!!! %s", err) + d.SetId("") + return nil + } + return WrapError(err) + } + + if objectRaw["data"] != nil { + d.Set("policy", objectRaw["data"]) + } + + parts := strings.Split(d.Id(), ":") + d.Set("project_name", parts[0]) + d.Set("role_name", parts[1]) + + return nil +} + +func resourceAliCloudMaxComputeRoleUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + var request map[string]interface{} + var response map[string]interface{} + var query map[string]*string + var body map[string]interface{} + update := false + + parts := strings.Split(d.Id(), ":") + projectName := parts[0] + roleName := parts[1] + action := fmt.Sprintf("/api/v1/projects/%s/roles/%s", projectName, roleName) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + body = make(map[string]interface{}) + + if d.HasChange("policy") { + update = true + } + if v, ok := d.GetOk("policy"); ok || d.HasChange("policy") { + request["policy"] = v + } + body = request + if update { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("PUT"), StringPointer("AK"), StringPointer(action), query, nil, body, &runtime) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + } + + return resourceAliCloudMaxComputeRoleRead(d, meta) +} + +func resourceAliCloudMaxComputeRoleDelete(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*connectivity.AliyunClient) + parts := strings.Split(d.Id(), ":") + projectName := parts[0] + roleName := parts[1] + action := fmt.Sprintf("/api/v1/projects/%s/roles/%s", projectName, roleName) + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]*string) + conn, err := client.NewOdpsClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("DELETE"), StringPointer("AK"), StringPointer(action), query, nil, nil, &runtime) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + + if err != nil { + if NotFoundError(err) { + return nil + } + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + + return nil +} diff --git a/alicloud/resource_alicloud_max_compute_role_test.go b/alicloud/resource_alicloud_max_compute_role_test.go new file mode 100644 index 000000000000..97419ae0e42b --- /dev/null +++ b/alicloud/resource_alicloud_max_compute_role_test.go @@ -0,0 +1,167 @@ +package alicloud + +import ( + "fmt" + "testing" + + "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +// Test MaxCompute Role. >>> Resource test cases, automatically generated. +// Case policyRole_terraform测试_typeAdmin 9618 +func TestAccAliCloudMaxComputeRole_basic9618(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_max_compute_role.default" + ra := resourceAttrInit(resourceId, AlicloudMaxComputeRoleMap9618) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &MaxComputeServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeMaxComputeRole") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(1, 999) + name := fmt.Sprintf("tf_testacc%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudMaxComputeRoleBasicDependence9618) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "role_name": name, + "type": "admin", + "project_name": "${alicloud_maxcompute_project.default.id}", + "policy": "{\\\"Statement\\\":[{\\\"Action\\\":[\\\"odps:*\\\"],\\\"Effect\\\":\\\"Allow\\\",\\\"Resource\\\":[\\\"acs:odps:*:projects/project_name/authorization/roles\\\",\\\"acs:odps:*:projects/project_name/authorization/roles/*/*\\\"]}],\\\"Version\\\":\\\"1\\\"}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "role_name": name, + "type": "admin", + "project_name": CHECKSET, + "policy": CHECKSET, + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "policy": "{\\\"Statement\\\":[{\\\"Action\\\":[\\\"odps:*\\\"],\\\"Effect\\\":\\\"Allow\\\",\\\"Resource\\\":[\\\"acs:odps:*:projects/project_name/authorization/packages\\\",\\\"acs:odps:*:projects/project_name/authorization/packages/*\\\",\\\"acs:odps:*:projects/project_name/authorization/packages/*/*/*\\\"]}],\\\"Version\\\":\\\"1\\\"}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "policy": CHECKSET, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"type"}, + }, + }, + }) +} + +var AlicloudMaxComputeRoleMap9618 = map[string]string{} + +func AlicloudMaxComputeRoleBasicDependence9618(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "project_name" { + default = "tf_test_project_20250109" +} + +resource "alicloud_maxcompute_project" "default" { + default_quota = "默认后付费Quota" + project_name = var.name + comment = var.name + product_type = "PayAsYouGo" +} + +`, name) +} + +// Case policyRole_terraform测试_typeResource 9584 +func TestAccAliCloudMaxComputeRole_basic9584(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_max_compute_role.default" + ra := resourceAttrInit(resourceId, AlicloudMaxComputeRoleMap9584) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &MaxComputeServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeMaxComputeRole") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(1, 999) + name := fmt.Sprintf("tf_testacc%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudMaxComputeRoleBasicDependence9584) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "role_name": name, + "type": "resource", + "project_name": "${alicloud_maxcompute_project.default.id}", + "policy": "{\\\"Version\\\":\\\"1\\\",\\\"Statement\\\":[{\\\"Action\\\":[\\\"odps:Select\\\"],\\\"Resource\\\":[\\\"acs:odps:*:projects/test_project_a/tables/tb_*\\\"],\\\"Effect\\\":\\\"Allow\\\"}]}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "role_name": name, + "type": "resource", + "project_name": CHECKSET, + "policy": CHECKSET, + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "policy": "{\\\"Version\\\":\\\"1\\\",\\\"Statement\\\":[{\\\"Action\\\":[\\\"odps:Update\\\"],\\\"Resource\\\":[\\\"acs:odps:*:projects/test_project_a/tables/tb_*\\\"],\\\"Effect\\\":\\\"Allow\\\"}]}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "policy": CHECKSET, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"type"}, + }, + }, + }) +} + +var AlicloudMaxComputeRoleMap9584 = map[string]string{} + +func AlicloudMaxComputeRoleBasicDependence9584(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +resource "alicloud_maxcompute_project" "default" { + default_quota = "默认后付费Quota" + project_name = var.name + comment = var.name + product_type = "PayAsYouGo" +} + +`, name) +} + +// Test MaxCompute Role. <<< Resource test cases, automatically generated. diff --git a/alicloud/service_alicloud_max_compute_v2.go b/alicloud/service_alicloud_max_compute_v2.go index cb11a7c9a0b6..d1a20900ace5 100644 --- a/alicloud/service_alicloud_max_compute_v2.go +++ b/alicloud/service_alicloud_max_compute_v2.go @@ -3,6 +3,7 @@ package alicloud import ( "encoding/json" "fmt" + "strings" "time" "github.com/PaesslerAG/jsonpath" @@ -237,3 +238,242 @@ func (s *MaxComputeServiceV2) SetResourceTags(d *schema.ResourceData, resourceTy } // SetResourceTags >>> tag function encapsulated. +// DescribeMaxComputeQuotaPlan <<< Encapsulated get interface for MaxCompute QuotaPlan. + +func (s *MaxComputeServiceV2) DescribeMaxComputeQuotaPlan(id string) (object map[string]interface{}, err error) { + client := s.client + var request map[string]interface{} + var response map[string]interface{} + var query map[string]*string + parts := strings.Split(id, ":") + if len(parts) != 2 { + err = WrapError(fmt.Errorf("invalid Resource Id %s. Expected parts' length %d, got %d", id, 2, len(parts))) + } + nickname := parts[0] + planName := parts[1] + conn, err := client.NewOdpsClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaPlan/%s", nickname, planName) + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("GET"), StringPointer("AK"), StringPointer(action), query, nil, nil, &runtime) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + if IsExpectedErrors(err, []string{"QUOTA_PLAN_NOT_FOUND"}) { + return object, WrapErrorf(Error(GetNotFoundMessage("QuotaPlan", id)), NotFoundMsg, response) + } + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + response = response["body"].(map[string]interface{}) + + v, err := jsonpath.Get("$.data", response) + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.data", response) + } + + return v.(map[string]interface{}), nil +} + +func (s *MaxComputeServiceV2) MaxComputeQuotaPlanStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeMaxComputeQuotaPlan(id) + if err != nil { + if NotFoundError(err) { + return object, "", nil + } + return nil, "", WrapError(err) + } + + v, err := jsonpath.Get(field, object) + currentStatus := fmt.Sprint(v) + + if strings.HasPrefix(field, "#") { + v, _ := jsonpath.Get(strings.TrimPrefix(field, "#"), object) + if v != nil { + currentStatus = "#CHECKSET" + } + } + + for _, failState := range failStates { + if currentStatus == failState { + return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } + } + return object, currentStatus, nil + } +} + +// DescribeMaxComputeQuotaPlan >>> Encapsulated. +// DescribeMaxComputeRole <<< Encapsulated get interface for MaxCompute Role. + +func (s *MaxComputeServiceV2) DescribeMaxComputeRole(id string) (object map[string]interface{}, err error) { + client := s.client + var request map[string]interface{} + var response map[string]interface{} + var query map[string]*string + parts := strings.Split(id, ":") + if len(parts) != 2 { + err = WrapError(fmt.Errorf("invalid Resource Id %s. Expected parts' length %d, got %d", id, 2, len(parts))) + } + projectName := parts[0] + roleName := parts[1] + conn, err := client.NewOdpsClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + + action := fmt.Sprintf("/api/v1/projects/%s/roles/%s/policy", projectName, roleName) + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("GET"), StringPointer("AK"), StringPointer(action), query, nil, nil, &runtime) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + if IsExpectedErrors(err, []string{"OBJECT_NOT_EXIST"}) { + return object, WrapErrorf(Error(GetNotFoundMessage("Role", id)), NotFoundMsg, response) + } + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + response = response["body"].(map[string]interface{}) + + return response, nil +} + +func (s *MaxComputeServiceV2) MaxComputeRoleStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeMaxComputeRole(id) + if err != nil { + if NotFoundError(err) { + return object, "", nil + } + return nil, "", WrapError(err) + } + + v, err := jsonpath.Get(field, object) + currentStatus := fmt.Sprint(v) + + if strings.HasPrefix(field, "#") { + v, _ := jsonpath.Get(strings.TrimPrefix(field, "#"), object) + if v != nil { + currentStatus = "#CHECKSET" + } + } + + for _, failState := range failStates { + if currentStatus == failState { + return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } + } + return object, currentStatus, nil + } +} + +// DescribeMaxComputeRole >>> Encapsulated. +// DescribeMaxComputeQuotaSchedule <<< Encapsulated get interface for MaxCompute QuotaSchedule. + +func (s *MaxComputeServiceV2) DescribeMaxComputeQuotaSchedule(id string) (object map[string]interface{}, err error) { + client := s.client + var request map[string]interface{} + var response map[string]interface{} + var query map[string]*string + parts := strings.Split(id, ":") + if len(parts) != 2 { + err = WrapError(fmt.Errorf("invalid Resource Id %s. Expected parts' length %d, got %d", id, 2, len(parts))) + } + nickname := parts[0] + conn, err := client.NewOdpsClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]*string) + query["displayTimezone"] = StringPointer(parts[1]) + + action := fmt.Sprintf("/api/v1/quotas/%s/computeQuotaSchedule", nickname) + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer("2022-01-04"), nil, StringPointer("GET"), StringPointer("AK"), StringPointer(action), query, nil, nil, &runtime) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + if err != nil { + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + response = response["body"].(map[string]interface{}) + + return response, nil +} + +func (s *MaxComputeServiceV2) MaxComputeQuotaScheduleStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeMaxComputeQuotaSchedule(id) + if err != nil { + if NotFoundError(err) { + return object, "", nil + } + return nil, "", WrapError(err) + } + + v, err := jsonpath.Get(field, object) + currentStatus := fmt.Sprint(v) + + if strings.HasPrefix(field, "#") { + v, _ := jsonpath.Get(strings.TrimPrefix(field, "#"), object) + if v != nil { + currentStatus = "#CHECKSET" + } + } + + for _, failState := range failStates { + if currentStatus == failState { + return object, currentStatus, WrapError(Error(FailedToReachTargetStatus, currentStatus)) + } + } + return object, currentStatus, nil + } +} + +// DescribeMaxComputeQuotaSchedule >>> Encapsulated. diff --git a/website/docs/r/max_compute_quota_plan.html.markdown b/website/docs/r/max_compute_quota_plan.html.markdown new file mode 100644 index 000000000000..71e2fcedd91e --- /dev/null +++ b/website/docs/r/max_compute_quota_plan.html.markdown @@ -0,0 +1,136 @@ +--- +subcategory: "Max Compute" +layout: "alicloud" +page_title: "Alicloud: alicloud_max_compute_quota_plan" +description: |- + Provides a Alicloud Max Compute Quota Plan resource. +--- + +# alicloud_max_compute_quota_plan + +Provides a Max Compute Quota Plan resource. + + + +For information about Max Compute Quota Plan and how to use it, see [What is Quota Plan](https://www.alibabacloud.com/help/en/). + +-> **NOTE:** Available since v1.242.0. + +## Example Usage + +Basic Usage + +```terraform +variable "name" { + default = "terraform-example" +} + +provider "alicloud" { + region = "cn-hangzhou" +} + + +variable "elastic_reserved_cu" { + default = "50" +} + +resource "alicloud_max_compute_quota_plan" "default" { + nickname = "os_terrform_p" + quota { + parameter { + elastic_reserved_cu = var.elastic_reserved_cu + } + + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "0" + max_cu = "20" + elastic_reserved_cu = var.elastic_reserved_cu + } + + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "50" + max_cu = "50" + elastic_reserved_cu = "0" + } + + } + + } + + plan_name = "quota_plan" +} +``` + +## Argument Reference + +The following arguments are supported: +* `is_effective` - (Optional) Whether to take effect immediately. “Valid values: true” +.-> **NOTE:** when other quota plans in the same quota group take effect, the effective quota group will become invalid. That is, IsEffective will become false. The effective quota plan cannot be deleted. +* `nickname` - (Required, ForceNew) Quota Name +* `plan_name` - (Required, ForceNew) The Quota plan name. Start with a letter, containing letters, numbers, and underscores (_). It is no more than 64 characters long. +* `quota` - (Optional, ForceNew, List) Quota property See [`quota`](#quota) below. + +### `quota` + +The quota supports the following: +* `parameter` - (Optional, ForceNew, List) The parameters of level-1 quota. See [`parameter`](#quota-parameter) below. +* `sub_quota_info_list` - (Optional, ForceNew, Set) Secondary Quota list + +-> **NOTE:** need to list all secondary Quota + See [`sub_quota_info_list`](#quota-sub_quota_info_list) below. + +### `quota-parameter` + +The quota-parameter supports the following: +* `elastic_reserved_cu` - (Required, Int) The value of elastic Reserved CUs. + +### `quota-sub_quota_info_list` + +The quota-sub_quota_info_list supports the following: +* `nick_name` - (Required, ForceNew) The nickname of the level-2 quota. +* `parameter` - (Optional, List) Level 2 Quota CU configuration See [`parameter`](#quota-sub_quota_info_list-parameter) below. + +### `quota-sub_quota_info_list-parameter` + +The quota-sub_quota_info_list-parameter supports the following: +* `elastic_reserved_cu` - (Required, Int) The value of elastic Reserved CUs. + +-> **NOTE:** The total number of elastically reserved CUs in all the level-2 quotas is equal to the number of elastically reserved CUs in the level-1 quota.. + +* `max_cu` - (Required, Int) The value of maxCU in Reserved CUs. + +-> **NOTE:** The value of maxCU must be less than or equal to the value of maxCU in the level-1 quota that you purchased. + +* `min_cu` - (Required, Int) The value of minCU in Reserved CUs. + +-> **NOTE:** -- The total value of minCU in all the level-2 quotas is equal to the value of minCU in the level-1 quota. -- The value of minCU must be less than or equal to the value of maxCU in the level-2 quota and less than or equal to the value of minCU in the level-1 quota that you purchased. + + +## Attributes Reference + +The following attributes are exported: +* `id` - The ID of the resource supplied above.The value is formulated as `:`. +* `quota` - Quota property + * `parameter` - The parameters of level-1 quota. + * `max_cu` - The value of maxCU in Reserved CUs. + * `min_cu` - The value of minCU in Reserved CUs. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration-0-11/resources.html#timeouts) for certain actions: +* `create` - (Defaults to 5 mins) Used when create the Quota Plan. +* `delete` - (Defaults to 5 mins) Used when delete the Quota Plan. +* `update` - (Defaults to 5 mins) Used when update the Quota Plan. + +## Import + +Max Compute Quota Plan can be imported using the id, e.g. + +```shell +$ terraform import alicloud_max_compute_quota_plan.example : +``` \ No newline at end of file diff --git a/website/docs/r/max_compute_quota_schedule.html.markdown b/website/docs/r/max_compute_quota_schedule.html.markdown new file mode 100644 index 000000000000..efefe521e583 --- /dev/null +++ b/website/docs/r/max_compute_quota_schedule.html.markdown @@ -0,0 +1,210 @@ +--- +subcategory: "Max Compute" +layout: "alicloud" +page_title: "Alicloud: alicloud_max_compute_quota_schedule" +description: |- + Provides a Alicloud Max Compute Quota Schedule resource. +--- + +# alicloud_max_compute_quota_schedule + +Provides a Max Compute Quota Schedule resource. + + + +For information about Max Compute Quota Schedule and how to use it, see [What is Quota Schedule](https://www.alibabacloud.com/help/en/). + +-> **NOTE:** Available since v1.242.0. + +## Example Usage + +Basic Usage + +```terraform +variable "name" { + default = "terraform-example" +} + +provider "alicloud" { + region = "cn-hangzhou" +} + +variable "elastic_reserved_cu" { + default = "0" +} + +variable "quota_nick_name" { + default = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_plan" "default" { + quota { + parameter { + elastic_reserved_cu = 50 + } + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "0" + max_cu = "20" + elastic_reserved_cu = "30" + } + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "50" + max_cu = "50" + elastic_reserved_cu = "20" + } + + } + } + + plan_name = "quota_plan1" + nickname = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_plan" "default2" { + quota { + parameter { + elastic_reserved_cu = 50 + } + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "0" + max_cu = "20" + elastic_reserved_cu = "20" + } + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "50" + max_cu = "50" + elastic_reserved_cu = "30" + } + + } + } + + plan_name = "quota_plan2" + nickname = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_plan" "default3" { + quota { + parameter { + elastic_reserved_cu = 50 + } + sub_quota_info_list { + nick_name = "sub_quota" + parameter { + min_cu = "40" + max_cu = "40" + elastic_reserved_cu = "40" + } + } + sub_quota_info_list { + nick_name = "os_terrform" + parameter { + min_cu = "10" + max_cu = "10" + elastic_reserved_cu = "10" + } + + } + } + + plan_name = "quota_plan3" + nickname = "os_terrform_p" +} + +resource "alicloud_max_compute_quota_schedule" "default" { + timezone = "UTC+8" + nickname = var.quota_nick_name + schedule_list { + plan = "Default" + condition { + at = "00:00" + } + + type = "daily" + } + + # schedule_list { + # plan = "${alicloud_max_compute_quota_plan.default.plan_name}" + # condition { + # at = "00:00" + # } + + # type = "daily" + # } + # schedule_list { + # type = "daily" + # plan = "${alicloud_max_compute_quota_plan.default2.plan_name}" + # condition { + # at = "01:00" + # } + + # } + # schedule_list { + # plan = "${alicloud_max_compute_quota_plan.default3.plan_name}" + # condition { + # at = "02:00" + # } + + # type = "daily" + # } + +} +``` + +### Deleting `alicloud_max_compute_quota_schedule` or removing it from your configuration + +Terraform cannot destroy resource `alicloud_max_compute_quota_schedule`. Terraform will remove this resource from the state file, however resources may remain. + +## Argument Reference + +The following arguments are supported: +* `nickname` - (Required, ForceNew) The nickname of level-1 compute quota. +* `schedule_list` - (Optional, Set) schedule list See [`schedule_list`](#schedule_list) below. +* `timezone` - (Required, ForceNew) Time zone, reference value: UTC +8 + +### `schedule_list` + +The schedule_list supports the following: +* `condition` - (Optional, List) The value of effective condition. See [`condition`](#schedule_list-condition) below. +* `plan` - (Required) The name of the quota plan. +* `type` - (Required, ForceNew) The type of the quota plan. Valid values: daily + +-> **NOTE:** Currently, only daily is supported. + + +### `schedule_list-condition` + +The schedule_list-condition supports the following: +* `at` - (Required) Effective time. The format is HH:mm, sample value: 00:00 + +-> **NOTE:** The configuration must start from the effective time of 00:00. The input time must be either a whole hour or a half hour, and the minimum interval between each schedule is 30 minutes. + + +## Attributes Reference + +The following attributes are exported: +* `id` - The ID of the resource supplied above.The value is formulated as `:`. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration-0-11/resources.html#timeouts) for certain actions: +* `create` - (Defaults to 5 mins) Used when create the Quota Schedule. +* `update` - (Defaults to 5 mins) Used when update the Quota Schedule. + +## Import + +Max Compute Quota Schedule can be imported using the id, e.g. + +```shell +$ terraform import alicloud_max_compute_quota_schedule.example : +``` \ No newline at end of file diff --git a/website/docs/r/max_compute_role.html.markdown b/website/docs/r/max_compute_role.html.markdown new file mode 100644 index 000000000000..448f5eb19d21 --- /dev/null +++ b/website/docs/r/max_compute_role.html.markdown @@ -0,0 +1,80 @@ +--- +subcategory: "Max Compute" +layout: "alicloud" +page_title: "Alicloud: alicloud_max_compute_role" +description: |- + Provides a Alicloud Max Compute Role resource. +--- + +# alicloud_max_compute_role + +Provides a Max Compute Role resource. + + + +For information about Max Compute Role and how to use it, see [What is Role](https://www.alibabacloud.com/help/en/). + +-> **NOTE:** Available since v1.242.0. + +## Example Usage + +Basic Usage + +```terraform +variable "name" { + default = "terraform-example" +} + +provider "alicloud" { + region = "cn-hangzhou" +} + +resource "alicloud_maxcompute_project" "default" { + default_quota = "默认后付费Quota" + project_name = var.name + comment = var.name + product_type = "PayAsYouGo" +} + +resource "alicloud_max_compute_role" "default" { + type = "admin" + project_name = alicloud_maxcompute_project.default.id + policy = jsonencode({ "Statement" : [{ "Action" : ["odps:*"], "Effect" : "Allow", "Resource" : ["acs:odps:*:projects/project_name/authorization/roles", "acs:odps:*:projects/project_name/authorization/roles/*/*"] }], "Version" : "1" }) + role_name = "tf_example112" +} +``` + +## Argument Reference + +The following arguments are supported: +* `policy` - (Optional, JsonString) Policy Authorization +Refer to [Policy-based access control](https://www.alibabacloud.com/help/en/maxcompute/user-guide/policy-based-access-control-1) and [Authorization practices](https://www.alibabacloud.com/help/en/maxcompute/use-cases/authorization-practices) +* `project_name` - (Required, ForceNew) Project name +* `role_name` - (Required, ForceNew) Role Name + +-> **NOTE:** At the beginning of a letter, it can contain letters and numbers and can be no more than 64 characters in length. + +* `type` - (Required) Role type Valid values: admin/resource + +-> **NOTE:** -- management type (admin) role: You can grant management type permissions through Policy. You cannot grant resource permissions to management type roles. You cannot grant management type permissions to management type roles through ACL. -- resource role: you can authorize resource type permissions through Policy or ACL, but cannot authorize management type permissions. For details, see [role-planning](https://www.alibabacloud.com/help/en/maxcompute/user-guide/role-planning) + + +## Attributes Reference + +The following attributes are exported: +* `id` - The ID of the resource supplied above.The value is formulated as `:`. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration-0-11/resources.html#timeouts) for certain actions: +* `create` - (Defaults to 5 mins) Used when create the Role. +* `delete` - (Defaults to 5 mins) Used when delete the Role. +* `update` - (Defaults to 5 mins) Used when update the Role. + +## Import + +Max Compute Role can be imported using the id, e.g. + +```shell +$ terraform import alicloud_max_compute_role.example : +``` \ No newline at end of file