diff --git a/alicloud/resource_alicloud_pai_workspace_workspace.go b/alicloud/resource_alicloud_pai_workspace_workspace.go index 2801d43ed61d..cdf0d25ec258 100644 --- a/alicloud/resource_alicloud_pai_workspace_workspace.go +++ b/alicloud/resource_alicloud_pai_workspace_workspace.go @@ -21,7 +21,7 @@ func resourceAliCloudPaiWorkspaceWorkspace() *schema.Resource { State: schema.ImportStatePassthrough, }, Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), + Create: schema.DefaultTimeout(6 * time.Minute), Update: schema.DefaultTimeout(5 * time.Minute), Delete: schema.DefaultTimeout(5 * time.Minute), }, @@ -37,13 +37,19 @@ func resourceAliCloudPaiWorkspaceWorkspace() *schema.Resource { "display_name": { Type: schema.TypeString, Optional: true, + Computed: true, }, "env_types": { - Type: schema.TypeList, + Type: schema.TypeSet, Required: true, ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "resource_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, "status": { Type: schema.TypeString, Computed: true, @@ -75,12 +81,17 @@ func resourceAliCloudPaiWorkspaceWorkspaceCreate(d *schema.ResourceData, meta in request["DisplayName"] = v } if v, ok := d.GetOk("env_types"); ok { - envTypesMaps := v.([]interface{}) - request["EnvTypes"] = envTypesMaps + envTypesMapsArray := convertToInterfaceArray(v) + + request["EnvTypes"] = envTypesMapsArray + } + + if v, ok := d.GetOk("resource_group_id"); ok { + request["ResourceGroupId"] = v } body = request - wait := incrementalWait(3*time.Second, 5*time.Second) + wait := incrementalWait(3*time.Second, 0*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { response, err = client.RoaPost("AIWorkSpace", "2021-02-04", action, query, nil, body, true) if err != nil { @@ -123,28 +134,19 @@ func resourceAliCloudPaiWorkspaceWorkspaceRead(d *schema.ResourceData, meta inte return WrapError(err) } - if objectRaw["GmtCreateTime"] != nil { - d.Set("create_time", objectRaw["GmtCreateTime"]) - } - if objectRaw["Description"] != nil { - d.Set("description", objectRaw["Description"]) - } - if objectRaw["DisplayName"] != nil { - d.Set("display_name", objectRaw["DisplayName"]) - } - if objectRaw["Status"] != nil { - d.Set("status", objectRaw["Status"]) - } - if objectRaw["WorkspaceName"] != nil { - d.Set("workspace_name", objectRaw["WorkspaceName"]) - } + d.Set("create_time", objectRaw["GmtCreateTime"]) + d.Set("description", objectRaw["Description"]) + d.Set("display_name", objectRaw["DisplayName"]) + d.Set("resource_group_id", objectRaw["ResourceGroupId"]) + d.Set("status", objectRaw["Status"]) + d.Set("workspace_name", objectRaw["WorkspaceName"]) - envTypes1Raw := make([]interface{}, 0) + envTypesRaw := make([]interface{}, 0) if objectRaw["EnvTypes"] != nil { - envTypes1Raw = objectRaw["EnvTypes"].([]interface{}) + envTypesRaw = convertToInterfaceArray(objectRaw["EnvTypes"]) } - d.Set("env_types", envTypes1Raw) + d.Set("env_types", envTypesRaw) return nil } @@ -156,9 +158,11 @@ func resourceAliCloudPaiWorkspaceWorkspaceUpdate(d *schema.ResourceData, meta in var query map[string]*string var body map[string]interface{} update := false + d.Partial(true) + + var err error WorkspaceId := d.Id() action := fmt.Sprintf("/api/v1/workspaces/%s", WorkspaceId) - var err error request = make(map[string]interface{}) query = make(map[string]*string) body = make(map[string]interface{}) @@ -176,7 +180,7 @@ func resourceAliCloudPaiWorkspaceWorkspaceUpdate(d *schema.ResourceData, meta in request["Description"] = d.Get("description") body = request if update { - wait := incrementalWait(3*time.Second, 5*time.Second) + wait := incrementalWait(3*time.Second, 0*time.Second) err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { response, err = client.RoaPut("AIWorkSpace", "2021-02-04", action, query, nil, body, true) if err != nil { @@ -193,6 +197,41 @@ func resourceAliCloudPaiWorkspaceWorkspaceUpdate(d *schema.ResourceData, meta in return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } } + update = false + action = fmt.Sprintf("/resourcegroups/action/changeresourcegroup") + request = make(map[string]interface{}) + query = make(map[string]*string) + body = make(map[string]interface{}) + request["ResourceId"] = d.Id() + + if _, ok := d.GetOk("resource_group_id"); ok && d.HasChange("resource_group_id") { + update = true + } + if v, ok := d.GetOk("resource_group_id"); ok || d.HasChange("resource_group_id") { + request["NewResourceGroupId"] = v + } + request["ResourceType"] = "workspace" + body = request + if update { + wait := incrementalWait(3*time.Second, 0*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RoaPut("AIWorkSpace", "2021-02-04", action, query, nil, body, true) + 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) + } + } + + d.Partial(false) return resourceAliCloudPaiWorkspaceWorkspaceRead(d, meta) } @@ -232,7 +271,7 @@ func resourceAliCloudPaiWorkspaceWorkspaceDelete(d *schema.ResourceData, meta in } paiWorkspaceServiceV2 := PaiWorkspaceServiceV2{client} - stateConf := BuildStateConf([]string{}, []string{}, d.Timeout(schema.TimeoutDelete), 5*time.Second, paiWorkspaceServiceV2.PaiWorkspaceWorkspaceStateRefreshFunc(d.Id(), "Status", []string{})) + stateConf := BuildStateConf([]string{}, []string{""}, d.Timeout(schema.TimeoutDelete), 5*time.Second, paiWorkspaceServiceV2.PaiWorkspaceWorkspaceStateRefreshFunc(d.Id(), "Status", []string{})) if _, err := stateConf.WaitForState(); err != nil { return WrapErrorf(err, IdMsg, d.Id()) } diff --git a/alicloud/resource_alicloud_pai_workspace_workspace_test.go b/alicloud/resource_alicloud_pai_workspace_workspace_test.go index 09a9c419ce4d..c0002bc3d71c 100644 --- a/alicloud/resource_alicloud_pai_workspace_workspace_test.go +++ b/alicloud/resource_alicloud_pai_workspace_workspace_test.go @@ -14,7 +14,7 @@ import ( func TestAccAliCloudPaiWorkspaceWorkspace_basic7875(t *testing.T) { var v map[string]interface{} resourceId := "alicloud_pai_workspace_workspace.default" - ra := resourceAttrInit(resourceId, AlicloudPaiWorkspaceWorkspaceMap7875) + ra := resourceAttrInit(resourceId, AliCloudPaiWorkspaceWorkspaceMap7875) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { return &PaiWorkspaceServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} }, "DescribePaiWorkspaceWorkspace") @@ -22,7 +22,7 @@ func TestAccAliCloudPaiWorkspaceWorkspace_basic7875(t *testing.T) { testAccCheck := rac.resourceAttrMapUpdateSet() rand := acctest.RandIntRange(10000, 99999) name := fmt.Sprintf("tf_testaccworkspace%d", rand) - testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudPaiWorkspaceWorkspaceBasicDependence7875) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudPaiWorkspaceWorkspaceBasicDependence7875) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheckWithRegions(t, true, []connectivity.Region{"cn-hangzhou"}) @@ -36,7 +36,6 @@ func TestAccAliCloudPaiWorkspaceWorkspace_basic7875(t *testing.T) { Config: testAccConfig(map[string]interface{}{ "description": "452", "workspace_name": name, - "display_name": "test_pop_584", "env_types": []string{ "prod"}, }), @@ -44,35 +43,90 @@ func TestAccAliCloudPaiWorkspaceWorkspace_basic7875(t *testing.T) { testAccCheck(map[string]string{ "description": CHECKSET, "workspace_name": name, - "display_name": CHECKSET, "env_types.#": "1", }), ), }, { Config: testAccConfig(map[string]interface{}{ - "description": "184", "display_name": "new_test_pop_559", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ - "description": CHECKSET, "display_name": CHECKSET, }), ), }, { Config: testAccConfig(map[string]interface{}{ - "description": "986", - "display_name": "test_pop_403", + "description": "986", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ - "description": CHECKSET, "display_name": CHECKSET, }), ), }, + { + Config: testAccConfig(map[string]interface{}{ + "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.ids.1}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "resource_group_id": CHECKSET, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func TestAccAliCloudPaiWorkspaceWorkspace_basic7875_twin(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_pai_workspace_workspace.default" + ra := resourceAttrInit(resourceId, AliCloudPaiWorkspaceWorkspaceMap7875) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &PaiWorkspaceServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribePaiWorkspaceWorkspace") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tf_testaccworkspace%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudPaiWorkspaceWorkspaceBasicDependence7875) + 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{}{ + "description": "452", + "workspace_name": name, + "display_name": "new_test_pop_559", + "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.ids.1}", + "env_types": []string{ + "prod"}, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "description": CHECKSET, + "workspace_name": name, + "display_name": CHECKSET, + "resource_group_id": CHECKSET, + "env_types.#": "1", + }), + ), + }, { ResourceName: resourceId, ImportState: true, @@ -83,17 +137,20 @@ func TestAccAliCloudPaiWorkspaceWorkspace_basic7875(t *testing.T) { }) } -var AlicloudPaiWorkspaceWorkspaceMap7875 = map[string]string{ - "status": CHECKSET, - "create_time": CHECKSET, +var AliCloudPaiWorkspaceWorkspaceMap7875 = map[string]string{ + "status": CHECKSET, + "create_time": CHECKSET, + "resource_group_id": CHECKSET, + "display_name": CHECKSET, } -func AlicloudPaiWorkspaceWorkspaceBasicDependence7875(name string) string { +func AliCloudPaiWorkspaceWorkspaceBasicDependence7875(name string) string { return fmt.Sprintf(` variable "name" { default = "%s" } - +data "alicloud_resource_manager_resource_groups" "default" { +} `, name) } diff --git a/alicloud/service_alicloud_pai_workspace_v2.go b/alicloud/service_alicloud_pai_workspace_v2.go index 57a73c0605d4..8ae254ea9896 100644 --- a/alicloud/service_alicloud_pai_workspace_v2.go +++ b/alicloud/service_alicloud_pai_workspace_v2.go @@ -47,22 +47,33 @@ func (s *PaiWorkspaceServiceV2) DescribePaiWorkspaceWorkspace(id string) (object } return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) } + return response, nil } func (s *PaiWorkspaceServiceV2) PaiWorkspaceWorkspaceStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return s.PaiWorkspaceWorkspaceStateRefreshFuncWithApi(id, field, failStates, s.DescribePaiWorkspaceWorkspace) +} + +func (s *PaiWorkspaceServiceV2) PaiWorkspaceWorkspaceStateRefreshFuncWithApi(id string, field string, failStates []string, call func(id string) (map[string]interface{}, error)) resource.StateRefreshFunc { return func() (interface{}, string, error) { - object, err := s.DescribePaiWorkspaceWorkspace(id) + object, err := call(id) if err != nil { if NotFoundError(err) { - return nil, "", nil + 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)) diff --git a/website/docs/r/pai_workspace_workspace.html.markdown b/website/docs/r/pai_workspace_workspace.html.markdown index ed8ffd852150..b18b6f613c19 100644 --- a/website/docs/r/pai_workspace_workspace.html.markdown +++ b/website/docs/r/pai_workspace_workspace.html.markdown @@ -54,6 +54,7 @@ The following arguments are supported: * `env_types` - (Required, ForceNew, List) Environments contained in the workspace: - Simple mode only production environment (prod). - Standard mode includes development environment (dev) and production environment (prod). +* `resource_group_id` - (Optional, Computed, Available since v1.277.0) The ID of the resource group. * `workspace_name` - (Required, ForceNew) The workspace name. The format is as follows: - 3 to 23 characters in length and can contain letters, underscores, or numbers. - Must start with a large or small letter. @@ -91,4 +92,4 @@ PAI Workspace Workspace can be imported using the id, e.g. ```shell $ terraform import alicloud_pai_workspace_workspace.example -``` \ No newline at end of file +```