diff --git a/alicloud/provider.go b/alicloud/provider.go index 9cb638f6fe88..2eba638bb3f3 100644 --- a/alicloud/provider.go +++ b/alicloud/provider.go @@ -895,6 +895,7 @@ func Provider() terraform.ResourceProvider { "alicloud_vpc_ipam_ipams": dataSourceAliCloudVpcIpamIpams(), }, ResourcesMap: map[string]*schema.Resource{ + "alicloud_eais_client_instance_attachment": resourceAliCloudEaisClientInstanceAttachment(), "alicloud_resource_manager_auto_grouping_rule": resourceAliCloudResourceManagerAutoGroupingRule(), "alicloud_eflo_invocation": resourceAliCloudEfloInvocation(), "alicloud_eflo_cluster": resourceAliCloudEfloCluster(), diff --git a/alicloud/resource_alicloud_eais_client_instance_attachment.go b/alicloud/resource_alicloud_eais_client_instance_attachment.go new file mode 100644 index 000000000000..8d4d2490bc34 --- /dev/null +++ b/alicloud/resource_alicloud_eais_client_instance_attachment.go @@ -0,0 +1,332 @@ +package alicloud + +import ( + "fmt" + "log" + "strings" + "time" + + "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 resourceAliCloudEaisClientInstanceAttachment() *schema.Resource { + return &schema.Resource{ + Create: resourceAliCloudEaisClientInstanceAttachmentCreate, + Read: resourceAliCloudEaisClientInstanceAttachmentRead, + Update: resourceAliCloudEaisClientInstanceAttachmentUpdate, + Delete: resourceAliCloudEaisClientInstanceAttachmentDelete, + 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{ + "client_instance_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + }, + "ei_instance_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "category": { + Type: schema.TypeString, + Optional: true, + }, + "instance_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "region_id": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } +} + +func resourceAliCloudEaisClientInstanceAttachmentCreate(d *schema.ResourceData, meta interface{}) error { + + client := meta.(*connectivity.AliyunClient) + if InArray(fmt.Sprint(d.Get("category")), []string{"eais", ""}) { + action := "AttachEai" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + if v, ok := d.GetOk("instance_id"); ok { + request["ElasticAcceleratedInstanceId"] = v + } + if v, ok := d.GetOk("client_instance_id"); ok { + request["ClientInstanceId"] = v + } + request["RegionId"] = client.RegionId + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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, "alicloud_eais_client_instance_attachment", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprintf("%v:%v", response["ElasticAcceleratedInstanceId"], response["ClientInstanceId"])) + + } + + if v, ok := d.GetOk("category"); ok && InArray(fmt.Sprint(v), []string{"ei"}) { + action := "AttachEaisEi" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + if v, ok := d.GetOk("instance_id"); ok { + request["EiInstanceId"] = v + } + if v, ok := d.GetOk("client_instance_id"); ok { + request["ClientInstanceId"] = v + } + request["RegionId"] = client.RegionId + + if v, ok := d.GetOk("ei_instance_type"); ok { + request["EiInstanceType"] = v + } + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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, "alicloud_eais_client_instance_attachment", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprintf("%v:%v", response["EiInstanceId"], response["ClientInstanceId"])) + + } + + return resourceAliCloudEaisClientInstanceAttachmentUpdate(d, meta) +} + +func resourceAliCloudEaisClientInstanceAttachmentRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + eaisServiceV2 := EaisServiceV2{client} + + objectRaw, err := eaisServiceV2.DescribeEaisClientInstanceAttachment(d.Id()) + if err != nil { + if !d.IsNewResource() && NotFoundError(err) { + log.Printf("[DEBUG] Resource alicloud_eais_client_instance_attachment DescribeEaisClientInstanceAttachment Failed!!! %s", err) + d.SetId("") + return nil + } + return WrapError(err) + } + + d.Set("create_time", objectRaw["StartTime"]) + d.Set("ei_instance_type", objectRaw["InstanceType"]) + d.Set("region_id", objectRaw["RegionId"]) + d.Set("status", objectRaw["Status"]) + d.Set("client_instance_id", objectRaw["ClientInstanceId"]) + d.Set("instance_id", objectRaw["ElasticAcceleratedInstanceId"]) + + return nil +} + +func resourceAliCloudEaisClientInstanceAttachmentUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) + var request map[string]interface{} + var response map[string]interface{} + var query map[string]interface{} + + enableAction := false + if v, ok := d.GetOk("category"); ok && InArray(fmt.Sprint(v), []string{"ei"}) { + enableAction = true + } + if enableAction && d.HasChange("status") { + eaisServiceV2 := EaisServiceV2{client} + object, err := eaisServiceV2.DescribeEaisClientInstanceAttachment(d.Id()) + if err != nil { + return WrapError(err) + } + + target := d.Get("status").(string) + if object["Status"].(string) != target { + if target == "InUse" { + parts := strings.Split(d.Id(), ":") + action := "StartEaisEi" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["EiInstanceId"] = parts[0] + request["RegionId"] = client.RegionId + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + + } + if target == "Bound" { + parts := strings.Split(d.Id(), ":") + action := "StopEaisEi" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["EiInstanceId"] = parts[0] + request["RegionId"] = client.RegionId + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + + } + } + } + + return resourceAliCloudEaisClientInstanceAttachmentRead(d, meta) +} + +func resourceAliCloudEaisClientInstanceAttachmentDelete(d *schema.ResourceData, meta interface{}) error { + + enableDelete := false + if InArray(fmt.Sprint(d.Get("category")), []string{"eais", ""}) { + enableDelete = true + } + if enableDelete { + client := meta.(*connectivity.AliyunClient) + parts := strings.Split(d.Id(), ":") + action := "DetachEai" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["ElasticAcceleratedInstanceId"] = parts[0] + request["RegionId"] = client.RegionId + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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 { + if NotFoundError(err) { + return nil + } + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + + } + + enableDelete = false + if v, ok := d.GetOk("category"); ok { + if InArray(fmt.Sprint(v), []string{"ei"}) { + enableDelete = true + } + } + if enableDelete { + client := meta.(*connectivity.AliyunClient) + parts := strings.Split(d.Id(), ":") + action := "DetachEaisEi" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["EiInstanceId"] = parts[0] + request["RegionId"] = client.RegionId + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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 { + if NotFoundError(err) { + return nil + } + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + + } + return nil +} diff --git a/alicloud/resource_alicloud_eais_client_instance_attachment_test.go b/alicloud/resource_alicloud_eais_client_instance_attachment_test.go new file mode 100644 index 000000000000..b6883021e1db --- /dev/null +++ b/alicloud/resource_alicloud_eais_client_instance_attachment_test.go @@ -0,0 +1,436 @@ +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 Eais ClientInstanceAttachment. >>> Resource test cases, automatically generated. +// Case ca_ei_pro 10133 +func TestAccAliCloudEaisClientInstanceAttachment_basic10133(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_eais_client_instance_attachment.default" + ra := resourceAttrInit(resourceId, AlicloudEaisClientInstanceAttachmentMap10133) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &EaisServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeEaisClientInstanceAttachment") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tfacceais%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudEaisClientInstanceAttachmentBasicDependence10133) + 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{}{ + "instance_id": "${alicloud_eais_instance.eais.id}", + "client_instance_id": "${alicloud_instance.example.id}", + "category": "ei", + "status": "Bound", + "ei_instance_type": "eais.ei-a6.2xlarge", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_id": CHECKSET, + "client_instance_id": CHECKSET, + "status": "Bound", + "ei_instance_type": "eais.ei-a6.2xlarge", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "status": "InUse", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "status": "InUse", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "status": "Bound", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "status": "Bound", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"category"}, + }, + }, + }) +} + +var AlicloudEaisClientInstanceAttachmentMap10133 = map[string]string{ + "create_time": CHECKSET, + "region_id": CHECKSET, +} + +func AlicloudEaisClientInstanceAttachmentBasicDependence10133(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "zone" { + default = "cn-hangzhou-i" +} + +variable "ecs_image" { + default = "ubuntu_20_04_x64_20G_alibase_20230316.vhd" +} + +variable "ecs_type" { + default = "ecs.g7.large" +} + +variable "region" { + default = "cn-hangzhou" +} + +variable "category" { + default = "ei" +} + +data "alicloud_zones" "default" { + available_resource_creation = "VSwitch" +} + +data "alicloud_instance_types" "example" { + availability_zone = "cn-hangzhou-i" + cpu_core_count = 1 + memory_size = 2 +} + +data "alicloud_images" "example" { + name_regex = "^ubuntu_18.*64" + owners = "system" +} + +resource "alicloud_vpc" "example" { + vpc_name = var.name + cidr_block = "10.4.0.0/16" +} + +resource "alicloud_vswitch" "example" { + vswitch_name = var.name + cidr_block = "10.4.0.0/24" + vpc_id = alicloud_vpc.example.id + zone_id = "cn-hangzhou-i" +} + +resource "alicloud_security_group" "example" { + security_group_name = var.name + description = var.name + vpc_id = alicloud_vpc.example.id +} + +resource "alicloud_instance" "example" { + availability_zone = "cn-hangzhou-i" + vswitch_id = alicloud_vswitch.example.id + image_id = data.alicloud_images.example.images.0.id + instance_type = data.alicloud_instance_types.example.instance_types.0.id + system_disk_category = "cloud_efficiency" + internet_charge_type = "PayByTraffic" + internet_max_bandwidth_out = 5 + security_groups = [alicloud_security_group.example.id] + instance_name = var.name + user_data = "echo 'net.ipv4.ip_forward=1'>> /etc/sysctl.conf" +} + +resource "alicloud_eais_instance" "eais" { + instance_name = var.name + vswitch_id = alicloud_vswitch.example.id + security_group_id = alicloud_security_group.example.id + instance_type = "eais.ei-a6.2xlarge" + category = "ei" +} + + +`, name) +} + +// Case ca_eai_pro 10134 +func TestAccAliCloudEaisClientInstanceAttachment_basic10134(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_eais_client_instance_attachment.default" + ra := resourceAttrInit(resourceId, AlicloudEaisClientInstanceAttachmentMap10134) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &EaisServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeEaisClientInstanceAttachment") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tfacceais%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudEaisClientInstanceAttachmentBasicDependence10134) + 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{}{ + "instance_id": "${alicloud_eais_instance.eais.id}", + "client_instance_id": "${alicloud_instance.example.id}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_id": CHECKSET, + "client_instance_id": CHECKSET, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +var AlicloudEaisClientInstanceAttachmentMap10134 = map[string]string{ + "create_time": CHECKSET, + "region_id": CHECKSET, +} + +func AlicloudEaisClientInstanceAttachmentBasicDependence10134(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "zone" { + default = "cn-hangzhou-i" +} + +variable "ecs_image" { + default = "ubuntu_20_04_x64_20G_alibase_20230316.vhd" +} + +variable "ecs_type" { + default = "ecs.g7.large" +} + +variable "region" { + default = "cn-hangzhou" +} + +variable "category" { + default = "eais" +} + +data "alicloud_zones" "default" { + available_resource_creation = "VSwitch" +} + +data "alicloud_instance_types" "example" { + availability_zone = "cn-hangzhou-i" + cpu_core_count = 1 + memory_size = 2 +} + +data "alicloud_images" "example" { + name_regex = "^ubuntu_18.*64" + owners = "system" +} + +resource "alicloud_vpc" "example" { + vpc_name = var.name + cidr_block = "10.4.0.0/16" +} + +resource "alicloud_vswitch" "example" { + vswitch_name = var.name + cidr_block = "10.4.0.0/24" + vpc_id = alicloud_vpc.example.id + zone_id = "cn-hangzhou-i" +} + +resource "alicloud_security_group" "example" { + security_group_name = var.name + description = var.name + vpc_id = alicloud_vpc.example.id +} + +resource "alicloud_instance" "example" { + availability_zone = "cn-hangzhou-i" + vswitch_id = alicloud_vswitch.example.id + image_id = data.alicloud_images.example.images.0.id + instance_type = data.alicloud_instance_types.example.instance_types.0.id + system_disk_category = "cloud_efficiency" + internet_charge_type = "PayByTraffic" + internet_max_bandwidth_out = 5 + security_groups = [alicloud_security_group.example.id] + instance_name = var.name + user_data = "echo 'net.ipv4.ip_forward=1'>> /etc/sysctl.conf" +} + +resource "alicloud_eais_instance" "eais" { + instance_name = var.name + vswitch_id = alicloud_vswitch.example.id + security_group_id = alicloud_security_group.example.id + instance_type = "eais.ei-a6.2xlarge" +} + + +`, name) +} + +// Case ca_pre_eai 10092 +func TestAccAliCloudEaisClientInstanceAttachment_basic10092(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_eais_client_instance_attachment.default" + ra := resourceAttrInit(resourceId, AlicloudEaisClientInstanceAttachmentMap10092) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &EaisServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeEaisClientInstanceAttachment") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tfacceais%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudEaisClientInstanceAttachmentBasicDependence10092) + 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{}{ + "instance_id": "${alicloud_eais_instance.eais.id}", + "client_instance_id": "${alicloud_instance.example.id}", + "category": "eais", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_id": CHECKSET, + "client_instance_id": CHECKSET, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"category"}, + }, + }, + }) +} + +var AlicloudEaisClientInstanceAttachmentMap10092 = map[string]string{ + "create_time": CHECKSET, + "region_id": CHECKSET, +} + +func AlicloudEaisClientInstanceAttachmentBasicDependence10092(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "zone" { + default = "cn-hangzhou-i" +} + +variable "ecs_image" { + default = "ubuntu_20_04_x64_20G_alibase_20230316.vhd" +} + +variable "ecs_type" { + default = "ecs.g7.large" +} + +variable "region" { + default = "cn-hangzhou" +} + +variable "category" { + default = "eais" +} + +data "alicloud_zones" "default" { + available_resource_creation = "VSwitch" +} + +data "alicloud_instance_types" "example" { + availability_zone = "cn-hangzhou-i" + cpu_core_count = 1 + memory_size = 2 +} + +data "alicloud_images" "example" { + name_regex = "^ubuntu_18.*64" + owners = "system" +} + +resource "alicloud_vpc" "example" { + vpc_name = var.name + cidr_block = "10.4.0.0/16" +} + +resource "alicloud_vswitch" "example" { + vswitch_name = var.name + cidr_block = "10.4.0.0/24" + vpc_id = alicloud_vpc.example.id + zone_id = "cn-hangzhou-i" +} + +resource "alicloud_security_group" "example" { + security_group_name = var.name + description = var.name + vpc_id = alicloud_vpc.example.id +} + +resource "alicloud_instance" "example" { + availability_zone = "cn-hangzhou-i" + vswitch_id = alicloud_vswitch.example.id + image_id = data.alicloud_images.example.images.0.id + instance_type = data.alicloud_instance_types.example.instance_types.0.id + system_disk_category = "cloud_efficiency" + internet_charge_type = "PayByTraffic" + internet_max_bandwidth_out = 5 + security_groups = [alicloud_security_group.example.id] + instance_name = var.name + user_data = "echo 'net.ipv4.ip_forward=1'>> /etc/sysctl.conf" +} + +resource "alicloud_eais_instance" "eais" { + instance_name = var.name + vswitch_id = alicloud_vswitch.example.id + security_group_id = alicloud_security_group.example.id + instance_type = "eais.ei-a6.2xlarge" +} + + +`, name) +} + +// Test Eais ClientInstanceAttachment. <<< Resource test cases, automatically generated. diff --git a/alicloud/resource_alicloud_eais_instance.go b/alicloud/resource_alicloud_eais_instance.go index 4ca4cd7a9e2c..6d344cb878ca 100644 --- a/alicloud/resource_alicloud_eais_instance.go +++ b/alicloud/resource_alicloud_eais_instance.go @@ -1,10 +1,12 @@ package alicloud import ( + "encoding/json" "fmt" "log" "time" + "github.com/PaesslerAG/jsonpath" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" @@ -21,156 +23,497 @@ func resourceAliCloudEaisInstance() *schema.Resource { }, 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{ + "create_time": { + Type: schema.TypeString, + Computed: true, + }, + "environment_var": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "value": { + Type: schema.TypeString, + Optional: true, + }, + "key": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "image": { + Type: schema.TypeString, + Optional: true, + }, + "instance_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, "instance_type": { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: StringInSlice([]string{"eais.ei-a6.4xlarge", "eais.ei-a6.2xlarge", "eais.ei-a6.xlarge", "eais.ei-a6.large", "eais.ei-a6.medium"}, false), + ValidateFunc: StringInSlice([]string{"eais.ei-a6.2xlarge", "eais.ei-a6.medium"}, false), }, - "vswitch_id": { + "region_id": { Type: schema.TypeString, - Required: true, - ForceNew: true, + Computed: true, + }, + "resource_group_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, }, "security_group_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "instance_name": { + "status": { Type: schema.TypeString, Optional: true, - ForceNew: true, Computed: true, }, - "force": { - Type: schema.TypeBool, - Optional: true, + "tags": tagsSchema(), + "vswitch_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, }, - "status": { + "category": { Type: schema.TypeString, + Optional: true, Computed: true, }, + "force": { + Type: schema.TypeBool, + Optional: true, + Deprecated: "Field 'force' is deprecated and will be removed in a future release.", + }, }, } } func resourceAliCloudEaisInstanceCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - eaisService := EaisService{client} - var response map[string]interface{} - action := "CreateEai" - request := make(map[string]interface{}) - var err error + if InArray(fmt.Sprint(d.Get("category")), []string{"eais", ""}) { + action := "CreateEai" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["RegionId"] = client.RegionId + request["ClientToken"] = buildClientToken(action) - request["RegionId"] = client.RegionId - request["ClientToken"] = buildClientToken("CreateEai") - request["InstanceType"] = d.Get("instance_type") - request["VSwitchId"] = d.Get("vswitch_id") - request["SecurityGroupId"] = d.Get("security_group_id") + if v, ok := d.GetOk("resource_group_id"); ok { + request["ResourceGroupId"] = v + } + if v, ok := d.GetOk("tags"); ok { + tagsMap := ConvertTags(v.(map[string]interface{})) + request = expandTagsToMap(request, tagsMap) + } - if v, ok := d.GetOk("instance_name"); ok { - request["InstanceName"] = v - } + request["InstanceType"] = d.Get("instance_type") + if v, ok := d.GetOk("instance_name"); ok { + request["InstanceName"] = v + } + request["SecurityGroupId"] = d.Get("security_group_id") + request["VSwitchId"] = d.Get("vswitch_id") + if v, ok := d.GetOk("image"); ok { + request["Image"] = v + } + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, true) + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) - wait := incrementalWait(3*time.Second, 3*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError { - response, err = client.RpcPost("eais", "2019-06-24", action, nil, request, true) if err != nil { - if NeedRetry(err) { - wait() - return resource.RetryableError(err) + return WrapErrorf(err, DefaultErrorMsg, "alicloud_eais_instance", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprint(response["ElasticAcceleratedInstanceId"])) + + eaisServiceV2 := EaisServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutCreate), 30*time.Second, eaisServiceV2.EaisInstanceStateRefreshFunc(d.Id(), "Status", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + + } + + if v, ok := d.GetOk("category"); ok && InArray(fmt.Sprint(v), []string{"jupyter"}) { + action := "CreateEaiJupyter" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["RegionId"] = client.RegionId + request["ClientToken"] = buildClientToken(action) + + if v, ok := d.GetOk("resource_group_id"); ok { + request["ResourceGroupId"] = v + } + if v, ok := d.GetOk("tags"); ok { + tagsMap := ConvertTags(v.(map[string]interface{})) + request = expandTagsToMap(request, tagsMap) + } + + request["SecurityGroupId"] = d.Get("security_group_id") + request["VSwitchId"] = d.Get("vswitch_id") + if v, ok := d.GetOk("instance_name"); ok { + request["EaisName"] = v + } + if v, ok := d.GetOk("environment_var"); ok { + environmentVarMapsArray := make([]interface{}, 0) + for _, dataLoop1 := range v.([]interface{}) { + dataLoop1Tmp := dataLoop1.(map[string]interface{}) + dataLoop1Map := make(map[string]interface{}) + dataLoop1Map["Value"] = dataLoop1Tmp["value"] + dataLoop1Map["Key"] = dataLoop1Tmp["key"] + environmentVarMapsArray = append(environmentVarMapsArray, dataLoop1Map) + } + environmentVarMapsJson, err := json.Marshal(environmentVarMapsArray) + if err != nil { + return WrapError(err) } - return resource.NonRetryableError(err) + request["EnvironmentVar"] = string(environmentVarMapsJson) + } + + request["EaisType"] = d.Get("instance_type") + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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, "alicloud_eais_instance", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprint(response["ElasticAcceleratedInstanceId"])) + + eaisServiceV2 := EaisServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"InUse"}, d.Timeout(schema.TimeoutCreate), 30*time.Second, eaisServiceV2.EaisInstanceStateRefreshFunc(d.Id(), "Status", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) } - return nil - }) - addDebug(action, response, request) - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, "alicloud_eais_instance", action, AlibabaCloudSdkGoERROR) } - d.SetId(fmt.Sprint(response["ElasticAcceleratedInstanceId"])) + if v, ok := d.GetOk("category"); ok && InArray(fmt.Sprint(v), []string{"ei"}) { + action := "CreateEaisEi" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["RegionId"] = client.RegionId + request["ClientToken"] = buildClientToken(action) + + if v, ok := d.GetOk("resource_group_id"); ok { + request["ResourceGroupId"] = v + } + if v, ok := d.GetOk("tags"); ok { + tagsMap := ConvertTags(v.(map[string]interface{})) + request = expandTagsToMap(request, tagsMap) + } + + if v, ok := d.GetOk("instance_name"); ok { + request["InstanceName"] = v + } + request["InstanceType"] = d.Get("instance_type") + request["VSwitchId"] = d.Get("vswitch_id") + request["SecurityGroupId"] = d.Get("security_group_id") + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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, "alicloud_eais_instance", action, AlibabaCloudSdkGoERROR) + } + + d.SetId(fmt.Sprint(response["EiInstanceId"])) + + eaisServiceV2 := EaisServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Bindable"}, d.Timeout(schema.TimeoutCreate), 30*time.Second, eaisServiceV2.EaisInstanceStateRefreshFunc(d.Id(), "Status", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } - stateConf := BuildStateConf([]string{}, []string{"Available"}, d.Timeout(schema.TimeoutCreate), 5*time.Second, eaisService.EaisInstanceStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) } - return resourceAliCloudEaisInstanceRead(d, meta) + return resourceAliCloudEaisInstanceUpdate(d, meta) } func resourceAliCloudEaisInstanceRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - eaisService := EaisService{client} + eaisServiceV2 := EaisServiceV2{client} - object, err := eaisService.DescribeEaisInstance(d.Id()) + objectRaw, err := eaisServiceV2.DescribeEaisInstance(d.Id()) if err != nil { if !d.IsNewResource() && NotFoundError(err) { - log.Printf("[DEBUG] Resource alicloud_eais_instance eaisService.DescribeEaisInstance Failed!!! %s", err) + log.Printf("[DEBUG] Resource alicloud_eais_instance DescribeEaisInstance Failed!!! %s", err) d.SetId("") return nil } return WrapError(err) } - d.Set("instance_type", object["InstanceType"]) - d.Set("vswitch_id", object["VSwitchId"]) - d.Set("security_group_id", object["SecurityGroupId"]) - d.Set("instance_name", object["InstanceName"]) - d.Set("status", object["Status"]) + d.Set("create_time", objectRaw["CreationTime"]) + d.Set("instance_name", objectRaw["InstanceName"]) + d.Set("instance_type", objectRaw["InstanceType"]) + d.Set("region_id", objectRaw["RegionId"]) + d.Set("resource_group_id", objectRaw["ResourceGroupId"]) + d.Set("security_group_id", objectRaw["SecurityGroupId"]) + d.Set("status", objectRaw["Status"]) + d.Set("vswitch_id", objectRaw["VSwitchId"]) + + tagsMaps, _ := jsonpath.Get("$.Tags.Tag", objectRaw) + d.Set("tags", tagsToMap(tagsMaps)) return nil } func resourceAliCloudEaisInstanceUpdate(d *schema.ResourceData, meta interface{}) error { - log.Println(fmt.Sprintf("[WARNING] The resouce has not update operation.")) - return resourceAliCloudEaisInstanceRead(d, meta) -} - -func resourceAliCloudEaisInstanceDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - eaisService := EaisService{client} - action := "DeleteEai" + var request map[string]interface{} var response map[string]interface{} + var query map[string]interface{} + update := false + + if d.HasChange("status") { + eaisServiceV2 := EaisServiceV2{client} + object, err := eaisServiceV2.DescribeEaisInstance(d.Id()) + if err != nil { + return WrapError(err) + } + + target := d.Get("status").(string) + if object["Status"].(string) != target { + enableAction := false + if v, ok := d.GetOk("category"); ok && InArray(fmt.Sprint(v), []string{"jupyter"}) { + enableAction = true + } + if target == "Stopped" && enableAction { + action := "StopEaiJupyter" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["InstanceId"] = d.Id() + request["RegionId"] = client.RegionId + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + eaisServiceV2 := EaisServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"Stopped"}, d.Timeout(schema.TimeoutUpdate), 30*time.Second, eaisServiceV2.EaisInstanceStateRefreshFunc(d.Id(), "Status", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + + } + if target == "InUse" && enableAction { + action := "StartEaiJupyter" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["InstanceId"] = d.Id() + request["RegionId"] = client.RegionId + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + eaisServiceV2 := EaisServiceV2{client} + stateConf := BuildStateConf([]string{}, []string{"InUse"}, d.Timeout(schema.TimeoutUpdate), 30*time.Second, eaisServiceV2.EaisInstanceStateRefreshFunc(d.Id(), "Status", []string{})) + if _, err := stateConf.WaitForState(); err != nil { + return WrapErrorf(err, IdMsg, d.Id()) + } + + } + } + } var err error + action := "ChangeResourceGroup" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ResourceId"] = d.Id() + request["ResourceRegionId"] = client.RegionId + if _, ok := d.GetOk("resource_group_id"); ok && !d.IsNewResource() && d.HasChange("resource_group_id") { + update = true + } + request["ResourceGroupId"] = d.Get("resource_group_id") + if update { + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + } - request := map[string]interface{}{ - "RegionId": client.RegionId, - "ElasticAcceleratedInstanceId": d.Id(), + if d.HasChange("tags") { + eaisServiceV2 := EaisServiceV2{client} + if err := eaisServiceV2.SetResourceTags(d, "instance"); err != nil { + return WrapError(err) + } } + return resourceAliCloudEaisInstanceRead(d, meta) +} + +func resourceAliCloudEaisInstanceDelete(d *schema.ResourceData, meta interface{}) error { - if v, ok := d.GetOkExists("force"); ok { - request["Force"] = v + enableDelete := true + if v, ok := d.GetOk("category"); ok { + if InArray(fmt.Sprint(v), []string{"ei"}) { + enableDelete = false + log.Printf("[WARN] Cannot destroy resource alicloud_eais_instance which category valued ei. Terraform will remove this resource from the state file, however resources may remain.") + } } + if enableDelete { + client := meta.(*connectivity.AliyunClient) + action := "DeleteEai" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["ElasticAcceleratedInstanceId"] = d.Id() + request["RegionId"] = client.RegionId + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, true) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) - wait := incrementalWait(3*time.Second, 3*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { - response, err = client.RpcPost("eais", "2019-06-24", action, nil, request, false) if err != nil { - if NeedRetry(err) { - wait() - return resource.RetryableError(err) + if NotFoundError(err) { + return nil } - return resource.NonRetryableError(err) + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - return nil - }) - addDebug(action, response, request) - if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } - stateConf := BuildStateConf([]string{}, []string{}, d.Timeout(schema.TimeoutDelete), 5*time.Second, eaisService.EaisInstanceStateRefreshFunc(d.Id(), []string{})) - if _, err := stateConf.WaitForState(); err != nil { - return WrapErrorf(err, IdMsg, d.Id()) + enableDelete = false + if v, ok := d.GetOk("category"); ok { + if InArray(fmt.Sprint(v), []string{"ei"}) { + enableDelete = true + } } + if enableDelete { + client := meta.(*connectivity.AliyunClient) + action := "DeleteEaisEi" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + var err error + request = make(map[string]interface{}) + request["EiInstanceId"] = d.Id() + request["RegionId"] = client.RegionId + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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 { + if IsExpectedErrors(err, []string{"InvalidParameter.InstanceId.NotFound"}) || NotFoundError(err) { + return nil + } + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) + } + + } return nil } diff --git a/alicloud/resource_alicloud_eais_instance_test.go b/alicloud/resource_alicloud_eais_instance_test.go index 769671dbda49..537cd80a54a8 100644 --- a/alicloud/resource_alicloud_eais_instance_test.go +++ b/alicloud/resource_alicloud_eais_instance_test.go @@ -138,6 +138,7 @@ func TestAccAliCloudEaisInstance_basic0(t *testing.T) { "instance_type": "eais.ei-a6.2xlarge", "vswitch_id": "${alicloud_vswitch.default.id}", "security_group_id": "${alicloud_security_group.default.id}", + "category": "eais", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -151,7 +152,7 @@ func TestAccAliCloudEaisInstance_basic0(t *testing.T) { ResourceName: resourceId, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"force"}, + ImportStateVerifyIgnore: []string{"category"}, }, }, }) @@ -430,3 +431,178 @@ func TestUnitAliCloudEaisInstance(t *testing.T) { } } + +// Test Eais Instance. >>> Resource test cases, automatically generated. +// Case cc_jupyter_pro 10128 +func TestAccAliCloudEaisInstance_basic10128(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_eais_instance.default" + ra := resourceAttrInit(resourceId, AlicloudEaisInstanceMap10128) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &EaisServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeEaisInstance") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(10000, 99999) + name := fmt.Sprintf("tfacceais%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AlicloudEaisInstanceBasicDependence10128) + 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{}{ + "instance_name": name, + "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.ids.0}", + "security_group_id": "${alicloud_security_group.sg.id}", + "vswitch_id": "${alicloud_vswitch.vsw.id}", + "instance_type": "eais.ei-a6.2xlarge", + "image": "registry-vpc.cn-hangzhou.aliyuncs.com/eai_beijing/eais-triton:v3.2.5-server", + "environment_var": []map[string]interface{}{ + { + "key": "testKey", + "value": "testValue", + }, + }, + "status": "InUse", + "category": "jupyter", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_name": name, + "resource_group_id": CHECKSET, + "security_group_id": CHECKSET, + "vswitch_id": CHECKSET, + "instance_type": "eais.ei-a6.2xlarge", + "environment_var.#": "1", + "status": "InUse", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "status": "Stopped", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "status": "Stopped", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "status": "InUse", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "status": "InUse", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "tags": map[string]string{ + "Created": "TF", + "For": "Test", + }, + "environment_var": []map[string]interface{}{ + { + "key": "testKey-update", + "value": "testValue-update", + }, + }, + "resource_group_id": "${data.alicloud_resource_manager_resource_groups.default.ids.1}", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "tags.%": "2", + "tags.Created": "TF", + "tags.For": "Test", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "tags": map[string]string{ + "Created": "TF-update", + "For": "Test-update", + }, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "tags.%": "2", + "tags.Created": "TF-update", + "tags.For": "Test-update", + }), + ), + }, + { + Config: testAccConfig(map[string]interface{}{ + "tags": REMOVEKEY, + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "tags.%": "0", + "tags.Created": REMOVEKEY, + "tags.For": REMOVEKEY, + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"environment_var", "image", "category"}, + }, + }, + }) +} + +var AlicloudEaisInstanceMap10128 = map[string]string{ + "create_time": CHECKSET, + "region_id": "cn-hangzhou", +} + +func AlicloudEaisInstanceBasicDependence10128(name string) string { + return fmt.Sprintf(` +variable "name" { + default = "%s" +} + +variable "zone" { + default = "cn-hangzhou-i" +} + +variable "region" { + default = "cn-hangzhou" +} + +data "alicloud_resource_manager_resource_groups" "default" {} + +resource "alicloud_vpc" "vpc" { + cidr_block = "172.16.0.0/12" + vpc_name = var.name +} + +resource "alicloud_vswitch" "vsw" { + vpc_id = alicloud_vpc.vpc.id + cidr_block = "172.16.0.0/24" + vswitch_name = alicloud_vpc.vpc.id + zone_id = var.zone +} + +resource "alicloud_security_group" "sg" { + security_group_name = alicloud_vpc.vpc.id + vpc_id = alicloud_vpc.vpc.id +} + + +`, name) +} + +// Test Eais Instance. <<< Resource test cases, automatically generated. diff --git a/alicloud/service_alicloud_eais_v2.go b/alicloud/service_alicloud_eais_v2.go new file mode 100644 index 000000000000..1fa7504089e4 --- /dev/null +++ b/alicloud/service_alicloud_eais_v2.go @@ -0,0 +1,265 @@ +package alicloud + +import ( + "fmt" + "strings" + "time" + + "github.com/PaesslerAG/jsonpath" + "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +type EaisServiceV2 struct { + client *connectivity.AliyunClient +} + +// DescribeEaisClientInstanceAttachment <<< Encapsulated get interface for Eais ClientInstanceAttachment. + +func (s *EaisServiceV2) DescribeEaisClientInstanceAttachment(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]interface{} + 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))) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ElasticAcceleratedInstanceIds"] = expandSingletonToList(parts[0]) + request["RegionId"] = client.RegionId + action := "DescribeEais" + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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 object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + v, err := jsonpath.Get("$.Instances.Instance[*]", response) + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.Instances.Instance[*]", response) + } + + if len(v.([]interface{})) == 0 { + return object, WrapErrorf(Error(GetNotFoundMessage("ClientInstanceAttachment", id)), NotFoundMsg, response) + } + + result, _ := v.([]interface{}) + for _, v := range result { + item := v.(map[string]interface{}) + if fmt.Sprint(item["ClientInstanceId"]) != parts[1] { + continue + } + return item, nil + } + return object, WrapErrorf(Error(GetNotFoundMessage("ClientInstanceAttachment", id)), NotFoundMsg, response) +} + +func (s *EaisServiceV2) EaisClientInstanceAttachmentStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeEaisClientInstanceAttachment(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 + } +} + +// DescribeEaisClientInstanceAttachment >>> Encapsulated. + +// DescribeEaisInstance <<< Encapsulated get interface for Eais Instance. + +func (s *EaisServiceV2) DescribeEaisInstance(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]interface{} + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ElasticAcceleratedInstanceIds"] = convertObjectToJsonString(expandSingletonToList(id)) + request["RegionId"] = client.RegionId + action := "DescribeEais" + + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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 { + if IsExpectedErrors(err, []string{"InvalidParameter.InstanceId.NotFound"}) { + return object, WrapErrorf(Error(GetNotFoundMessage("Instance", id)), NotFoundMsg, response) + } + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + v, err := jsonpath.Get("$.Instances.Instance[*]", response) + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.Instances.Instance[*]", response) + } + + if len(v.([]interface{})) == 0 { + return object, WrapErrorf(Error(GetNotFoundMessage("Instance", id)), NotFoundMsg, response) + } + + return v.([]interface{})[0].(map[string]interface{}), nil +} + +func (s *EaisServiceV2) EaisInstanceStateRefreshFunc(id string, field string, failStates []string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + object, err := s.DescribeEaisInstance(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 + } +} + +// DescribeEaisInstance >>> Encapsulated. + +// SetResourceTags <<< Encapsulated tag function for Eais. +func (s *EaisServiceV2) SetResourceTags(d *schema.ResourceData, resourceType string) error { + if d.HasChange("tags") { + var action string + var err error + client := s.client + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + + added, removed := parsingTags(d) + removedTagKeys := make([]string, 0) + for _, v := range removed { + if !ignoredTags(v, "") { + removedTagKeys = append(removedTagKeys, v) + } + } + if len(removedTagKeys) > 0 { + action = "UntagResources" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ResourceId.1"] = d.Id() + request["RegionId"] = client.RegionId + for i, key := range removedTagKeys { + request[fmt.Sprintf("TagKey.%d", i+1)] = key + } + + request["ResourceType"] = resourceType + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + + } + + if len(added) > 0 { + action = "TagResources" + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["ResourceId.1"] = d.Id() + request["RegionId"] = client.RegionId + count := 1 + for key, value := range added { + request[fmt.Sprintf("Tag.%d.Key", count)] = key + request[fmt.Sprintf("Tag.%d.Value", count)] = value + count++ + } + + request["ResourceType"] = resourceType + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { + response, err = client.RpcPost("eais", "2019-06-24", action, query, request, 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) + } + + } + } + + return nil +} + +// SetResourceTags >>> tag function encapsulated. diff --git a/website/docs/r/eais_client_instance_attachment.html.markdown b/website/docs/r/eais_client_instance_attachment.html.markdown new file mode 100644 index 000000000000..a97beff8b1a8 --- /dev/null +++ b/website/docs/r/eais_client_instance_attachment.html.markdown @@ -0,0 +1,151 @@ +--- +subcategory: "Elastic Accelerated Computing Instances (EAIS)" +layout: "alicloud" +page_title: "Alicloud: alicloud_eais_client_instance_attachment" +description: |- + Provides a Alicloud EAIS Client Instance Attachment resource. +--- + +# alicloud_eais_client_instance_attachment + +Provides a EAIS Client Instance Attachment resource. + +Bind an ECS or ECI instance. + +For information about EAIS Client Instance Attachment and how to use it, see [What is Client Instance Attachment](https://www.alibabacloud.com/help/en/resource-orchestration-service/latest/aliyun-eais-clientinstanceattachment). + +-> **NOTE:** Available since v1.246.0. + +## Example Usage + +Basic Usage + +```terraform +variable "name" { + default = "terraform-example" +} + +provider "alicloud" { + region = "cn-hangzhou" +} + +variable "zone" { + default = "cn-hangzhou-i" +} + +variable "ecs_image" { + default = "ubuntu_20_04_x64_20G_alibase_20230316.vhd" +} + +variable "ecs_type" { + default = "ecs.g7.large" +} + +variable "region" { + default = "cn-hangzhou" +} + +variable "category" { + default = "ei" +} + +data "alicloud_zones" "default" { + available_resource_creation = "VSwitch" +} + +data "alicloud_instance_types" "example" { + availability_zone = "cn-hangzhou-i" + cpu_core_count = 1 + memory_size = 2 +} + +data "alicloud_images" "example" { + name_regex = "^ubuntu_18.*64" + owners = "system" +} + +resource "alicloud_vpc" "example" { + vpc_name = var.name + cidr_block = "10.4.0.0/16" +} + +resource "alicloud_vswitch" "example" { + vswitch_name = var.name + cidr_block = "10.4.0.0/24" + vpc_id = alicloud_vpc.example.id + zone_id = "cn-hangzhou-i" +} + +resource "alicloud_security_group" "example" { + security_group_name = var.name + description = var.name + vpc_id = alicloud_vpc.example.id +} + +resource "alicloud_instance" "example" { + availability_zone = "cn-hangzhou-i" + vswitch_id = alicloud_vswitch.example.id + image_id = data.alicloud_images.example.images.0.id + instance_type = data.alicloud_instance_types.example.instance_types.0.id + system_disk_category = "cloud_efficiency" + internet_charge_type = "PayByTraffic" + internet_max_bandwidth_out = 5 + security_groups = [alicloud_security_group.example.id] + instance_name = var.name + user_data = "echo 'net.ipv4.ip_forward=1'>> /etc/sysctl.conf" +} + +resource "alicloud_eais_instance" "eais" { + instance_name = var.name + vswitch_id = alicloud_vswitch.example.id + security_group_id = alicloud_security_group.example.id + instance_type = "eais.ei-a6.2xlarge" + category = "ei" +} + + +resource "alicloud_eais_client_instance_attachment" "default" { + instance_id = alicloud_eais_instance.eais.id + client_instance_id = alicloud_instance.example.id + category = "ei" + status = "Bound" + ei_instance_type = "eais.ei-a6.2xlarge" +} +``` + +### Deleting `alicloud_eais_client_instance_attachment` or removing it from your configuration + +The `alicloud_eais_client_instance_attachment` resource allows you to manage `category = "eais"` instance, but Terraform cannot destroy it. +Deleting the subscription resource or removing it from your configuration will remove it from your state file and management, but will not destroy the Instance. +You can resume managing the subscription instance via the AlibabaCloud Console. + +## Argument Reference + +The following arguments are supported: +* `category` - (Optional) EAIS instance category, valid values: `eais`, `ei`, default is `eais`. +* `client_instance_id` - (Required, ForceNew) The ID of the ECS or ECI instance bound to the EAIS instance. +* `ei_instance_type` - (Optional, ForceNew) The Ei instance specification, which is used to filter matching specifications for updating. +* `instance_id` - (Required, ForceNew) The EAIS instance ID. +* `status` - (Optional, Computed) The status of the resource + +## Attributes Reference + +The following attributes are exported: +* `id` - The ID of the resource supplied above.The value is formulated as `:`. +* `create_time` - The creation time of the resource +* `region_id` - The region ID of the resource + +## 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 Client Instance Attachment. +* `delete` - (Defaults to 5 mins) Used when delete the Client Instance Attachment. +* `update` - (Defaults to 5 mins) Used when update the Client Instance Attachment. + +## Import + +EAIS Client Instance Attachment can be imported using the id, e.g. + +```shell +$ terraform import alicloud_eais_client_instance_attachment.example : +``` \ No newline at end of file diff --git a/website/docs/r/eais_instance.html.markdown b/website/docs/r/eais_instance.html.markdown index 25d16e735c1c..406244993713 100644 --- a/website/docs/r/eais_instance.html.markdown +++ b/website/docs/r/eais_instance.html.markdown @@ -2,16 +2,17 @@ subcategory: "Elastic Accelerated Computing Instances (EAIS)" layout: "alicloud" page_title: "Alicloud: alicloud_eais_instance" -sidebar_current: "docs-alicloud-resource-eais-instance" description: |- - Provides a Alicloud Elastic Accelerated Computing Instances (EAIS) Instance resource. + Provides a Alicloud EAIS Instance resource. --- # alicloud_eais_instance -Provides a Elastic Accelerated Computing Instances (EAIS) Instance resource. +Provides a EAIS Instance resource. -For information about Elastic Accelerated Computing Instances (EAIS) Instance and how to use it, see [What is Instance](https://www.alibabacloud.com/help/en/resource-orchestration-service/latest/aliyun-eais-instance). +Instance resource definition. + +For information about EAIS Instance and how to use it, see [What is Instance](https://www.alibabacloud.com/help/en/resource-orchestration-service/latest/aliyun-eais-instance). -> **NOTE:** Available since v1.137.0. @@ -19,12 +20,6 @@ For information about Elastic Accelerated Computing Instances (EAIS) Instance an Basic Usage -
- ```terraform variable "name" { default = "terraform-example" @@ -63,36 +58,51 @@ resource "alicloud_eais_instance" "default" { } ``` +### Deleting `alicloud_eais_instance` or removing it from your configuration + +The `alicloud_eais_instance` resource allows you to manage `category = "ei"` instance, but Terraform cannot destroy it. +Deleting the subscription resource or removing it from your configuration will remove it from your state file and management, but will not destroy the Instance. +You can resume managing the subscription instance via the AlibabaCloud Console. + ## Argument Reference The following arguments are supported: - -* `instance_type` - (Required, ForceNew) The type of the Instance. Valid values: `eais.ei-a6.4xlarge`, `eais.ei-a6.2xlarge`, `eais.ei-a6.xlarge`, `eais.ei-a6.large`, `eais.ei-a6.medium`. -* `vswitch_id` - (Required, ForceNew) The ID of the vSwitch. -* `security_group_id` - (Required, ForceNew) The ID of the security group. -* `instance_name` - (Optional, ForceNew) The name of the Instance. -* `force` - (Optional, Bool) Specifies whether to force delete the Instance. Default value: `false`. Valid values: - - `true`: Enable. - - `false`: Disable. +* `category` - (Optional) EAIS instance category, valid values: `eais`, `jupyter`, `ei`, default is `eais`. +* `environment_var` - (Optional, List, Available since v1.246.0) Setting environment variables in eais instance on Initialization See [`environment_var`](#environment_var) below. +* `force` - (Optional, Deprecated since v1.246.0) Whether to force the deletion when the instance status does not meet the deletion conditions. +* `image` - (Optional, Available since v1.246.0) EAIS instance image. +* `instance_name` - (Optional, ForceNew) Name of the instance +* `instance_type` - (Required, ForceNew) EAIS instance type +* `resource_group_id` - (Optional, Computed, Available since v1.246.0) The ID of the resource group +* `security_group_id` - (Required, ForceNew) Security group ID +* `status` - (Optional, Computed) The status of the resource +* `tags` - (Optional, Map, Available since v1.246.0) The tags. +* `vswitch_id` - (Required, ForceNew) Switch ID. + +### `environment_var` + +The environment_var supports the following: +* `key` - (Optional, Available since v1.246.0) Keys for environment variables +* `value` - (Optional, Available since v1.246.0) Values of environment variables ## Attributes Reference The following attributes are exported: - -* `id` - The resource ID in terraform of Instance. -* `status` - The status of the Instance. +* `id` - The ID of the resource supplied above. +* `create_time` - The creation time of the resource +* `region_id` - Region ID ## 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 Instance. * `delete` - (Defaults to 5 mins) Used when delete the Instance. +* `update` - (Defaults to 5 mins) Used when update the Instance. ## Import -Elastic Accelerated Computing Instances (EAIS) Instance can be imported using the id, e.g. +EAIS Instance can be imported using the id, e.g. ```shell $ terraform import alicloud_eais_instance.example -``` +``` \ No newline at end of file