From 684ee91ec26a7c00ff98bc86456c11f860f7f814 Mon Sep 17 00:00:00 2001 From: zengchen1024 Date: Fri, 17 May 2019 09:27:41 +0800 Subject: [PATCH 1/3] add service level to the sdkClient --- huaweicloud/config.go | 13 +++++++++++-- huaweicloud/resource_huaweicloud_dws_cluster.go | 6 +++--- .../resource_huaweicloud_dws_cluster_test.go | 4 ++-- huaweicloud/resource_huaweicloud_mls_instance.go | 6 +++--- .../resource_huaweicloud_mls_instance_test.go | 4 ++-- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/huaweicloud/config.go b/huaweicloud/config.go index 46276c6a6f..04e8babb18 100644 --- a/huaweicloud/config.go +++ b/huaweicloud/config.go @@ -22,6 +22,11 @@ import ( "github.com/huaweicloud/golangsdk/openstack/objectstorage/v1/swauth" ) +const ( + serviceProjectLevel string = "project" + serviceDomainLevel string = "domain" +) + type Config struct { AccessKey string SecretKey string @@ -640,9 +645,13 @@ func (c *Config) dcsV1Client(region string) (*golangsdk.ServiceClient, error) { }) } -func (c *Config) sdkClient(region, serviceType string) (*golangsdk.ServiceClient, error) { +func (c *Config) sdkClient(region, serviceType string, level string) (*golangsdk.ServiceClient, error) { + client := c.HwClient + if level == serviceDomainLevel { + client = c.DomainClient + } return huaweisdk.NewSDKClient( - c.HwClient, + client, golangsdk.EndpointOpts{ Region: c.determineRegion(region), Availability: c.getHwEndpointType(), diff --git a/huaweicloud/resource_huaweicloud_dws_cluster.go b/huaweicloud/resource_huaweicloud_dws_cluster.go index 944ef2e182..aa31e7741d 100644 --- a/huaweicloud/resource_huaweicloud_dws_cluster.go +++ b/huaweicloud/resource_huaweicloud_dws_cluster.go @@ -211,7 +211,7 @@ func resourceDwsCluster() *schema.Resource { func resourceDwsClusterCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - client, err := config.sdkClient(GetRegion(d, config), "dws") + client, err := config.sdkClient(GetRegion(d, config), "dws", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } @@ -400,7 +400,7 @@ func resourceDwsClusterCreate(d *schema.ResourceData, meta interface{}) error { func resourceDwsClusterRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - client, err := config.sdkClient(GetRegion(d, config), "dws") + client, err := config.sdkClient(GetRegion(d, config), "dws", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } @@ -519,7 +519,7 @@ func resourceDwsClusterRead(d *schema.ResourceData, meta interface{}) error { func resourceDwsClusterDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - client, err := config.sdkClient(GetRegion(d, config), "dws") + client, err := config.sdkClient(GetRegion(d, config), "dws", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } diff --git a/huaweicloud/resource_huaweicloud_dws_cluster_test.go b/huaweicloud/resource_huaweicloud_dws_cluster_test.go index 59a51a615c..3532b2cd88 100644 --- a/huaweicloud/resource_huaweicloud_dws_cluster_test.go +++ b/huaweicloud/resource_huaweicloud_dws_cluster_test.go @@ -68,7 +68,7 @@ resource "huaweicloud_dws_cluster" "cluster" { func testAccCheckDwsClusterDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - client, err := config.sdkClient(OS_REGION_NAME, "dws") + client, err := config.sdkClient(OS_REGION_NAME, "dws", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } @@ -98,7 +98,7 @@ func testAccCheckDwsClusterDestroy(s *terraform.State) error { func testAccCheckDwsClusterExists() resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - client, err := config.sdkClient(OS_REGION_NAME, "dws") + client, err := config.sdkClient(OS_REGION_NAME, "dws", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } diff --git a/huaweicloud/resource_huaweicloud_mls_instance.go b/huaweicloud/resource_huaweicloud_mls_instance.go index a50223419b..ac6298b510 100644 --- a/huaweicloud/resource_huaweicloud_mls_instance.go +++ b/huaweicloud/resource_huaweicloud_mls_instance.go @@ -187,7 +187,7 @@ func resourceMlsInstance() *schema.Resource { func resourceMlsInstanceCreate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - client, err := config.sdkClient(GetRegion(d, config), "mls") + client, err := config.sdkClient(GetRegion(d, config), "mls", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } @@ -323,7 +323,7 @@ func resourceMlsInstanceCreate(d *schema.ResourceData, meta interface{}) error { func resourceMlsInstanceRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - client, err := config.sdkClient(GetRegion(d, config), "mls") + client, err := config.sdkClient(GetRegion(d, config), "mls", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } @@ -404,7 +404,7 @@ func resourceMlsInstanceRead(d *schema.ResourceData, meta interface{}) error { func resourceMlsInstanceDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) - client, err := config.sdkClient(GetRegion(d, config), "mls") + client, err := config.sdkClient(GetRegion(d, config), "mls", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } diff --git a/huaweicloud/resource_huaweicloud_mls_instance_test.go b/huaweicloud/resource_huaweicloud_mls_instance_test.go index f0ec5141ac..0028092038 100644 --- a/huaweicloud/resource_huaweicloud_mls_instance_test.go +++ b/huaweicloud/resource_huaweicloud_mls_instance_test.go @@ -99,7 +99,7 @@ resource "huaweicloud_mls_instance" "instance" { func testAccCheckMlsInstanceDestroy(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - client, err := config.sdkClient(OS_REGION_NAME, "mls") + client, err := config.sdkClient(OS_REGION_NAME, "mls", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } @@ -129,7 +129,7 @@ func testAccCheckMlsInstanceDestroy(s *terraform.State) error { func testAccCheckMlsInstanceExists() resource.TestCheckFunc { return func(s *terraform.State) error { config := testAccProvider.Meta().(*Config) - client, err := config.sdkClient(OS_REGION_NAME, "mls") + client, err := config.sdkClient(OS_REGION_NAME, "mls", serviceProjectLevel) if err != nil { return fmt.Errorf("Error creating sdk client, err=%s", err) } From 6d487a62a40d6906ef08d66c9e2806321d41e76b Mon Sep 17 00:00:00 2001 From: zengchen1024 Date: Fri, 17 May 2019 09:33:25 +0800 Subject: [PATCH 2/3] add resource of cdm cluster --- huaweicloud/custom_functions.go | 21 + .../data_source_huaweicloud_cdm_flavors_v1.go | 163 ++ huaweicloud/provider.go | 2 + .../resource_huaweicloud_cdm_cluster_v1.go | 1424 +++++++++++++++++ ...esource_huaweicloud_cdm_cluster_v1_test.go | 125 ++ huaweicloud/transport.go | 67 +- website/docs/d/cdm_flavors_v1.html.markdown | 33 + website/docs/r/cdm_cluster_v1.html.markdown | 150 ++ website/huaweicloud.erb | 12 + 9 files changed, 1996 insertions(+), 1 deletion(-) create mode 100644 huaweicloud/custom_functions.go create mode 100644 huaweicloud/data_source_huaweicloud_cdm_flavors_v1.go create mode 100644 huaweicloud/resource_huaweicloud_cdm_cluster_v1.go create mode 100644 huaweicloud/resource_huaweicloud_cdm_cluster_v1_test.go create mode 100644 website/docs/d/cdm_flavors_v1.html.markdown create mode 100644 website/docs/r/cdm_cluster_v1.html.markdown diff --git a/huaweicloud/custom_functions.go b/huaweicloud/custom_functions.go new file mode 100644 index 0000000000..e57a45fdaf --- /dev/null +++ b/huaweicloud/custom_functions.go @@ -0,0 +1,21 @@ +package huaweicloud + +func expandCdmClusterV1CreateAutoRemind(d interface{}, arrayIndex map[string]int) (interface{}, error) { + email, _ := navigateValue(d, []string{"email"}, nil) + e, eok := email.([]interface{}) + + phone, _ := navigateValue(d, []string{"phone_num"}, nil) + p, pok := phone.([]interface{}) + + return (eok && len(e) > 0) || (pok && len(p) > 0), nil +} + +func expandCdmClusterV1CreateClusterIsScheduleBootOff(d interface{}, arrayIndex map[string]int) (interface{}, error) { + on, _ := navigateValue(d, []string{"schedule_boot_time"}, nil) + on1, ok1 := on.(string) + + off, _ := navigateValue(d, []string{"schedule_off_time"}, nil) + off1, ok2 := off.(string) + + return (ok1 && on1 != "") || (ok2 && off1 != ""), nil +} diff --git a/huaweicloud/data_source_huaweicloud_cdm_flavors_v1.go b/huaweicloud/data_source_huaweicloud_cdm_flavors_v1.go new file mode 100644 index 0000000000..5a837c79c1 --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_cdm_flavors_v1.go @@ -0,0 +1,163 @@ +package huaweicloud + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/huaweicloud/golangsdk" +) + +func dataSourceCdmFlavorV1() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCdmFlavorV1Read, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "version": { + Type: schema.TypeString, + Computed: true, + }, + "flavors": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceCdmFlavorV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + client, err := config.sdkClient(GetRegion(d, config), "cdm", serviceProjectLevel) + if err != nil { + return fmt.Errorf("Error creating sdk client, err=%s", err) + } + + dsid, err := getCdmDatastoreV1ID(client) + if err != nil { + return err + } + + version, fs, err := getCdmFlavorV1(client, dsid) + if err != nil { + return err + } + + d.SetId(version) + d.Set("version", version) + d.Set("flavors", fs) + return nil +} + +func getCdmDatastoreV1ID(client *golangsdk.ServiceClient) (string, error) { + url := client.ServiceURL("datastores") + r := golangsdk.Result{} + _, r.Err = client.Get(url, &r.Body, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if r.Err != nil { + return "", r.Err + } + + v, err := navigateValue(r.Body, []string{"datastores"}, nil) + if err != nil { + return "", err + } + + ds, ok := v.([]interface{}) + if !ok { + return "", fmt.Errorf("can not find datastore") + } + + for _, item := range ds { + name, err := navigateValue(item, []string{"name"}, nil) + if err != nil { + return "", err + } + if "cdm" == name.(string) { + dsid, err := navigateValue(item, []string{"id"}, nil) + if err != nil { + return "", err + } + return dsid.(string), nil + } + } + + return "", fmt.Errorf("didn't find the datastore id") +} + +func getCdmFlavorV1(client *golangsdk.ServiceClient, dsid string) (string, interface{}, error) { + url := client.ServiceURL("datastores", dsid, "flavors") + r := golangsdk.Result{} + _, r.Err = client.Get(url, &r.Body, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if r.Err != nil { + return "", nil, r.Err + } + + v, err := navigateValue(r.Body, []string{"versions"}, nil) + if err != nil { + return "", nil, err + } + vs, ok := v.([]interface{}) + if !ok { + return "", nil, fmt.Errorf("can not find flavor") + } + for _, item := range vs { + version, err := navigateValue(item, []string{"name"}, nil) + if err != nil { + return "", nil, err + } + flavors, err := navigateValue(item, []string{"flavors"}, nil) + if err != nil { + return "", nil, err + } + + fs, ok := flavors.([]interface{}) + if !ok { + return "", nil, fmt.Errorf("can not find flavor") + } + num := len(fs) + r := make([]interface{}, num, num) + for i := 0; i < num; i++ { + item := fs[i] + name, err := navigateValue(item, []string{"name"}, nil) + if err != nil { + return "", nil, err + } + fid, err := navigateValue(item, []string{"str_id"}, nil) + if err != nil { + return "", nil, err + } + + r[i] = map[string]interface{}{ + "id": fid, + "name": name, + } + } + return version.(string), r, nil + } + + return "", nil, fmt.Errorf("can not find flavor") +} diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index e9915abdfd..f077b014c2 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -224,6 +224,7 @@ func Provider() terraform.ResourceProvider { "huaweicloud_dcs_maintainwindow_v1": dataSourceDcsMaintainWindowV1(), "huaweicloud_dcs_product_v1": dataSourceDcsProductV1(), "huaweicloud_identity_role_v3": dataSourceIdentityRoleV3(), + "huaweicloud_cdm_flavors_v1": dataSourceCdmFlavorV1(), }, ResourcesMap: map[string]*schema.Resource{ @@ -306,6 +307,7 @@ func Provider() terraform.ResourceProvider { "huaweicloud_identity_user_v3": resourceIdentityUserV3(), "huaweicloud_identity_group_v3": resourceIdentityGroupV3(), "huaweicloud_identity_group_membership_v3": resourceIdentityGroupMembershipV3(), + "huaweicloud_cdm_cluster_v1": resourceCdmClusterV1(), }, ConfigureFunc: configureProvider, diff --git a/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go b/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go new file mode 100644 index 0000000000..b06f4e727b --- /dev/null +++ b/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go @@ -0,0 +1,1424 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file at +// https://www.github.com/huaweicloud/magic-modules +// +// ---------------------------------------------------------------------------- + +package huaweicloud + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/huaweicloud/golangsdk" +) + +func resourceCdmClusterV1() *schema.Resource { + return &schema.Resource{ + Create: resourceCdmClusterV1Create, + Read: resourceCdmClusterV1Read, + Delete: resourceCdmClusterV1Delete, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "availability_zone": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "flavor_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "security_group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "version": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "email": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "enterprise_project_id": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "is_auto_off": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + ForceNew: true, + }, + + "phone_num": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "schedule_boot_time": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "schedule_off_time": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "created": { + Type: schema.TypeString, + Computed: true, + }, + + "instances": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "public_ip": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "traffic_ip": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "publid_ip": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceCdmClusterV1UserInputParams(d *schema.ResourceData) map[string]interface{} { + return map[string]interface{}{ + "terraform_resource_data": d, + "availability_zone": d.Get("availability_zone"), + "email": d.Get("email"), + "enterprise_project_id": d.Get("enterprise_project_id"), + "flavor_id": d.Get("flavor_id"), + "is_auto_off": d.Get("is_auto_off"), + "name": d.Get("name"), + "phone_num": d.Get("phone_num"), + "schedule_boot_time": d.Get("schedule_boot_time"), + "schedule_off_time": d.Get("schedule_off_time"), + "security_group_id": d.Get("security_group_id"), + "subnet_id": d.Get("subnet_id"), + "version": d.Get("version"), + "vpc_id": d.Get("vpc_id"), + } +} + +func resourceCdmClusterV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + client, err := config.sdkClient(GetRegion(d, config), "cdm", serviceProjectLevel) + if err != nil { + return fmt.Errorf("Error creating sdk client, err=%s", err) + } + + opts := resourceCdmClusterV1UserInputParams(d) + + params, err := buildCdmClusterV1CreateParameters(opts, nil) + if err != nil { + return fmt.Errorf("Error building the request body of api(create), err=%s", err) + } + r, err := sendCdmClusterV1CreateRequest(d, params, client) + if err != nil { + return fmt.Errorf("Error creating CdmClusterV1, err=%s", err) + } + + timeout := d.Timeout(schema.TimeoutCreate) + obj, err := asyncWaitCdmClusterV1Create(d, config, r, client, timeout) + if err != nil { + return err + } + id, err := navigateValue(obj, []string{"id"}, nil) + if err != nil { + return fmt.Errorf("Error constructing id, err=%s", err) + } + d.SetId(id.(string)) + + return resourceCdmClusterV1Read(d, meta) +} + +func resourceCdmClusterV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + client, err := config.sdkClient(GetRegion(d, config), "cdm", serviceProjectLevel) + if err != nil { + return fmt.Errorf("Error creating sdk client, err=%s", err) + } + + res := make(map[string]interface{}) + + v, err := sendCdmClusterV1ReadRequest(d, client) + if err != nil { + return err + } + res["read"] = fillReadRespBody(v) + + return setCdmClusterV1Properties(d, res) +} + +func resourceCdmClusterV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + client, err := config.sdkClient(GetRegion(d, config), "cdm", serviceProjectLevel) + if err != nil { + return fmt.Errorf("Error creating sdk client, err=%s", err) + } + + url, err := replaceVars(d, "clusters/{id}", nil) + if err != nil { + return err + } + url = client.ServiceURL(url) + + opts := resourceCdmClusterV1UserInputParams(d) + params, err := buildCdmClusterV1DeleteParameters(opts, nil) + if err != nil { + return fmt.Errorf("Error building the request body of api(delete), err=%s", err) + } + + log.Printf("[DEBUG] Deleting Cluster %q", d.Id()) + r := golangsdk.Result{} + _, r.Err = client.Delete(url, &golangsdk.RequestOpts{ + OkCodes: successHTTPCodes, + JSONBody: params, + JSONResponse: nil, + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }, + }) + if r.Err != nil { + return fmt.Errorf("Error deleting Cluster %q, err=%s", d.Id(), r.Err) + } + + _, err = waitToFinish( + []string{"Done"}, []string{"Pending"}, + d.Timeout(schema.TimeoutCreate), + 1*time.Second, + func() (interface{}, string, error) { + _, err := client.Get(url, nil, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + return true, "Done", nil + } + return nil, "", nil + } + return true, "Pending", nil + }, + ) + return err +} + +func buildCdmClusterV1CreateParameters(opts map[string]interface{}, arrayIndex map[string]int) (interface{}, error) { + params := make(map[string]interface{}) + + v, err := expandCdmClusterV1CreateAutoRemind(opts, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + params["autoRemind"] = v + } + + v, err = expandCdmClusterV1CreateCluster(opts, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + params["cluster"] = v + } + + v, err = expandCdmClusterV1CreateEmail(opts, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + params["email"] = v + } + + v, err = expandCdmClusterV1CreatePhoneNum(opts, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + params["phoneNum"] = v + } + + return params, nil +} + +func expandCdmClusterV1CreateCluster(d interface{}, arrayIndex map[string]int) (interface{}, error) { + req := make(map[string]interface{}) + + v, err := expandCdmClusterV1CreateClusterDatastore(d, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["datastore"] = v + } + + v, err = expandCdmClusterV1CreateClusterInstances(d, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["instances"] = v + } + + v, err = navigateValue(d, []string{"is_auto_off"}, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["isAutoOff"] = v + } + + v, err = expandCdmClusterV1CreateClusterIsScheduleBootOff(d, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["isScheduleBootOff"] = v + } + + v, err = navigateValue(d, []string{"name"}, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["name"] = v + } + + v, err = navigateValue(d, []string{"schedule_boot_time"}, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["scheduleBootTime"] = v + } + + v, err = navigateValue(d, []string{"schedule_off_time"}, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["scheduleOffTime"] = v + } + + v, err = expandCdmClusterV1CreateClusterSysTags(d, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["sys_tags"] = v + } + + v, err = navigateValue(d, []string{"vpc_id"}, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["vpcId"] = v + } + + return req, nil +} + +func expandCdmClusterV1CreateClusterDatastore(d interface{}, arrayIndex map[string]int) (interface{}, error) { + req := make(map[string]interface{}) + + req["type"] = "cdm" + + v, err := navigateValue(d, []string{"version"}, arrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + req["version"] = v + } + + return req, nil +} + +func expandCdmClusterV1CreateClusterInstances(d interface{}, arrayIndex map[string]int) (interface{}, error) { + newArrayIndex := make(map[string]int) + if arrayIndex != nil { + for k, v := range arrayIndex { + newArrayIndex[k] = v + } + } + + n := 1 + req := make([]interface{}, 0, n) + for i := 0; i < n; i++ { + transformed := make(map[string]interface{}) + + v, err := navigateValue(d, []string{"availability_zone"}, newArrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + transformed["availability_zone"] = v + } + + v, err = navigateValue(d, []string{"flavor_id"}, newArrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + transformed["flavorRef"] = v + } + + v, err = expandCdmClusterV1CreateClusterInstancesNics(d, newArrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + transformed["nics"] = v + } + + transformed["type"] = "cdm" + + if len(transformed) > 0 { + req = append(req, transformed) + } + } + + return req, nil +} + +func expandCdmClusterV1CreateClusterInstancesNics(d interface{}, arrayIndex map[string]int) (interface{}, error) { + newArrayIndex := make(map[string]int) + if arrayIndex != nil { + for k, v := range arrayIndex { + newArrayIndex[k] = v + } + } + + n := 1 + req := make([]interface{}, 0, n) + for i := 0; i < n; i++ { + transformed := make(map[string]interface{}) + + v, err := navigateValue(d, []string{"subnet_id"}, newArrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + transformed["net-id"] = v + } + + v, err = navigateValue(d, []string{"security_group_id"}, newArrayIndex) + if err != nil { + return nil, err + } + if e, err := isEmptyValue(reflect.ValueOf(v)); err != nil { + return nil, err + } else if !e { + transformed["securityGroupId"] = v + } + + if len(transformed) > 0 { + req = append(req, transformed) + } + } + + return req, nil +} + +func expandCdmClusterV1CreateClusterSysTags(d interface{}, arrayIndex map[string]int) (interface{}, error) { + v, err := navigateValue(d, []string{"enterprise_project_id"}, arrayIndex) + if err != nil { + return nil, err + } + if v1, ok := v.([]interface{}); ok && len(v1) > 0 { + v2 := make([]interface{}, len(v1), len(v1)) + for i, j := range v1 { + v2[i] = map[string]string{ + "key": "_sys_enterprise_project_id", + "value": j.(string), + } + } + return v2, nil + } + return nil, nil +} + +func expandCdmClusterV1CreateEmail(d interface{}, arrayIndex map[string]int) (interface{}, error) { + v, err := navigateValue(d, []string{"email"}, arrayIndex) + if err != nil { + return nil, err + } + if v1, ok := v.([]interface{}); ok && len(v1) > 0 { + v2 := make([]string, len(v1), len(v1)) + for i, j := range v1 { + v2[i] = j.(string) + } + return strings.Join(v2, ","), nil + } + return "", nil +} + +func expandCdmClusterV1CreatePhoneNum(d interface{}, arrayIndex map[string]int) (interface{}, error) { + v, err := navigateValue(d, []string{"phone_num"}, arrayIndex) + if err != nil { + return nil, err + } + if v1, ok := v.([]interface{}); ok && len(v1) > 0 { + v2 := make([]string, len(v1), len(v1)) + for i, j := range v1 { + v2[i] = j.(string) + } + return strings.Join(v2, ","), nil + } + return "", nil +} + +func sendCdmClusterV1CreateRequest(d *schema.ResourceData, params interface{}, + client *golangsdk.ServiceClient) (interface{}, error) { + url := client.ServiceURL("clusters") + + r := golangsdk.Result{} + _, r.Err = client.Post(url, params, &r.Body, &golangsdk.RequestOpts{ + OkCodes: successHTTPCodes, + MoreHeaders: map[string]string{ + "X-Language": "en-us", + }, + }) + if r.Err != nil { + return nil, fmt.Errorf("Error running api(create), err=%s", r.Err) + } + return r.Body, nil +} + +func asyncWaitCdmClusterV1Create(d *schema.ResourceData, config *Config, result interface{}, + client *golangsdk.ServiceClient, timeout time.Duration) (interface{}, error) { + + data := make(map[string]string) + pathParameters := map[string][]string{ + "cluster_id": []string{"id"}, + } + for key, path := range pathParameters { + value, err := navigateValue(result, path, nil) + if err != nil { + return nil, fmt.Errorf("Error retrieving async operation path parameter, err=%s", err) + } + data[key] = value.(string) + } + + url, err := replaceVars(d, "clusters/{cluster_id}", data) + if err != nil { + return nil, err + } + url = client.ServiceURL(url) + + return waitToFinish( + []string{"200"}, + []string{"100"}, + timeout, 1*time.Second, + func() (interface{}, string, error) { + r := golangsdk.Result{} + _, r.Err = client.Get(url, &r.Body, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if r.Err != nil { + return nil, "", nil + } + + status, err := navigateValue(r.Body, []string{"status"}, nil) + if err != nil { + return nil, "", nil + } + return r.Body, status.(string), nil + }, + ) +} + +func buildCdmClusterV1DeleteParameters(opts map[string]interface{}, arrayIndex map[string]int) (interface{}, error) { + params := make(map[string]interface{}) + + params["keepLastManualBackup"] = 0 + + return params, nil +} + +func sendCdmClusterV1ReadRequest(d *schema.ResourceData, client *golangsdk.ServiceClient) (interface{}, error) { + url, err := replaceVars(d, "clusters/{id}", nil) + if err != nil { + return nil, err + } + url = client.ServiceURL(url) + + r := golangsdk.Result{} + _, r.Err = client.Get(url, &r.Body, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if r.Err != nil { + return nil, fmt.Errorf("Error running api(read) for resource(CdmClusterV1), err=%s", r.Err) + } + + return r.Body, nil +} + +func fillReadRespBody(body interface{}) interface{} { + result := make(map[string]interface{}) + val, ok := body.(map[string]interface{}) + if !ok { + val = make(map[string]interface{}) + } + + if v, ok := val["actionProgress"]; ok { + result["actionProgress"] = v + } else { + result["actionProgress"] = nil + } + + if v, ok := val["actions"]; ok { + result["actions"] = v + } else { + result["actions"] = nil + } + + if v, ok := val["azName"]; ok { + result["azName"] = v + } else { + result["azName"] = nil + } + + if v, ok := val["clusterMode"]; ok { + result["clusterMode"] = v + } else { + result["clusterMode"] = nil + } + + if v, ok := val["config_status"]; ok { + result["config_status"] = v + } else { + result["config_status"] = nil + } + + if v, ok := val["created"]; ok { + result["created"] = v + } else { + result["created"] = nil + } + + if v, ok := val["customerConfig"]; ok { + result["customerConfig"] = fillReadRespCustomerConfig(v) + } else { + result["customerConfig"] = nil + } + + if v, ok := val["datastore"]; ok { + result["datastore"] = fillReadRespDatastore(v) + } else { + result["datastore"] = nil + } + + if v, ok := val["dbuser"]; ok { + result["dbuser"] = v + } else { + result["dbuser"] = nil + } + + if v, ok := val["eipId"]; ok { + result["eipId"] = v + } else { + result["eipId"] = nil + } + + if v, ok := val["endpointDomainName"]; ok { + result["endpointDomainName"] = v + } else { + result["endpointDomainName"] = nil + } + + if v, ok := val["flavorName"]; ok { + result["flavorName"] = v + } else { + result["flavorName"] = nil + } + + if v, ok := val["id"]; ok { + result["id"] = v + } else { + result["id"] = nil + } + + if v, ok := val["instances"]; ok { + result["instances"] = fillReadRespInstances(v) + } else { + result["instances"] = nil + } + + if v, ok := val["isAutoOff"]; ok { + result["isAutoOff"] = v + } else { + result["isAutoOff"] = nil + } + + if v, ok := val["isFrozen"]; ok { + result["isFrozen"] = v + } else { + result["isFrozen"] = nil + } + + if v, ok := val["isScheduleBootOff"]; ok { + result["isScheduleBootOff"] = v + } else { + result["isScheduleBootOff"] = nil + } + + if v, ok := val["links"]; ok { + result["links"] = fillReadRespLinks(v) + } else { + result["links"] = nil + } + + if v, ok := val["maintainWindow"]; ok { + result["maintainWindow"] = fillReadRespMaintainWindow(v) + } else { + result["maintainWindow"] = nil + } + + if v, ok := val["name"]; ok { + result["name"] = v + } else { + result["name"] = nil + } + + if v, ok := val["publicEndpoint"]; ok { + result["publicEndpoint"] = v + } else { + result["publicEndpoint"] = nil + } + + if v, ok := val["publicEndpointDomainName"]; ok { + result["publicEndpointDomainName"] = v + } else { + result["publicEndpointDomainName"] = nil + } + + if v, ok := val["publicEndpointStatus"]; ok { + result["publicEndpointStatus"] = fillReadRespPublicEndpointStatus(v) + } else { + result["publicEndpointStatus"] = nil + } + + if v, ok := val["recentEvent"]; ok { + result["recentEvent"] = v + } else { + result["recentEvent"] = nil + } + + if v, ok := val["status"]; ok { + result["status"] = v + } else { + result["status"] = nil + } + + if v, ok := val["statusDetail"]; ok { + result["statusDetail"] = v + } else { + result["statusDetail"] = nil + } + + if v, ok := val["task"]; ok { + result["task"] = fillReadRespTask(v) + } else { + result["task"] = nil + } + + if v, ok := val["updated"]; ok { + result["updated"] = v + } else { + result["updated"] = nil + } + + return result +} + +func fillReadRespCustomerConfig(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["clusterName"]; ok { + result["clusterName"] = v + } else { + result["clusterName"] = nil + } + + if v, ok := value1["failureRemind"]; ok { + result["failureRemind"] = v + } else { + result["failureRemind"] = nil + } + + if v, ok := value1["localDisk"]; ok { + result["localDisk"] = v + } else { + result["localDisk"] = nil + } + + if v, ok := value1["serviceProvider"]; ok { + result["serviceProvider"] = v + } else { + result["serviceProvider"] = nil + } + + if v, ok := value1["ssl"]; ok { + result["ssl"] = v + } else { + result["ssl"] = nil + } + + return result +} + +func fillReadRespDatastore(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["type"]; ok { + result["type"] = v + } else { + result["type"] = nil + } + + if v, ok := value1["version"]; ok { + result["version"] = v + } else { + result["version"] = nil + } + + return result +} + +func fillReadRespInstances(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.([]interface{}) + if !ok || len(value1) == 0 { + return nil + } + + n := len(value1) + result := make([]interface{}, n, n) + for i := 0; i < n; i++ { + val := make(map[string]interface{}) + item := value1[i].(map[string]interface{}) + + if v, ok := item["config_status"]; ok { + val["config_status"] = v + } else { + val["config_status"] = nil + } + + if v, ok := item["flavor"]; ok { + val["flavor"] = fillReadRespInstancesFlavor(v) + } else { + val["flavor"] = nil + } + + if v, ok := item["group"]; ok { + val["group"] = v + } else { + val["group"] = nil + } + + if v, ok := item["id"]; ok { + val["id"] = v + } else { + val["id"] = nil + } + + if v, ok := item["isFrozen"]; ok { + val["isFrozen"] = v + } else { + val["isFrozen"] = nil + } + + if v, ok := item["links_2"]; ok { + val["links_2"] = fillReadRespInstancesLinks2(v) + } else { + val["links_2"] = nil + } + + if v, ok := item["managerIp"]; ok { + val["managerIp"] = v + } else { + val["managerIp"] = nil + } + + if v, ok := item["name"]; ok { + val["name"] = v + } else { + val["name"] = nil + } + + if v, ok := item["paramsGroupId"]; ok { + val["paramsGroupId"] = v + } else { + val["paramsGroupId"] = nil + } + + if v, ok := item["publicIp"]; ok { + val["publicIp"] = v + } else { + val["publicIp"] = nil + } + + if v, ok := item["role"]; ok { + val["role"] = v + } else { + val["role"] = nil + } + + if v, ok := item["shard_id"]; ok { + val["shard_id"] = v + } else { + val["shard_id"] = nil + } + + if v, ok := item["status"]; ok { + val["status"] = v + } else { + val["status"] = nil + } + + if v, ok := item["trafficIp"]; ok { + val["trafficIp"] = v + } else { + val["trafficIp"] = nil + } + + if v, ok := item["type"]; ok { + val["type"] = v + } else { + val["type"] = nil + } + + if v, ok := item["volume"]; ok { + val["volume"] = fillReadRespInstancesVolume(v) + } else { + val["volume"] = nil + } + + result[i] = val + } + + return result +} + +func fillReadRespInstancesFlavor(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["id"]; ok { + result["id"] = v + } else { + result["id"] = nil + } + + if v, ok := value1["links_1"]; ok { + result["links_1"] = fillReadRespInstancesFlavorLinks1(v) + } else { + result["links_1"] = nil + } + + return result +} + +func fillReadRespInstancesFlavorLinks1(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.([]interface{}) + if !ok || len(value1) == 0 { + return nil + } + + n := len(value1) + result := make([]interface{}, n, n) + for i := 0; i < n; i++ { + val := make(map[string]interface{}) + item := value1[i].(map[string]interface{}) + + if v, ok := item["href"]; ok { + val["href"] = v + } else { + val["href"] = nil + } + + if v, ok := item["rel"]; ok { + val["rel"] = v + } else { + val["rel"] = nil + } + + result[i] = val + } + + return result +} + +func fillReadRespInstancesLinks2(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.([]interface{}) + if !ok || len(value1) == 0 { + return nil + } + + n := len(value1) + result := make([]interface{}, n, n) + for i := 0; i < n; i++ { + val := make(map[string]interface{}) + item := value1[i].(map[string]interface{}) + + if v, ok := item["href"]; ok { + val["href"] = v + } else { + val["href"] = nil + } + + if v, ok := item["rel"]; ok { + val["rel"] = v + } else { + val["rel"] = nil + } + + result[i] = val + } + + return result +} + +func fillReadRespInstancesVolume(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["size"]; ok { + result["size"] = v + } else { + result["size"] = nil + } + + if v, ok := value1["type"]; ok { + result["type"] = v + } else { + result["type"] = nil + } + + return result +} + +func fillReadRespLinks(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.([]interface{}) + if !ok || len(value1) == 0 { + return nil + } + + n := len(value1) + result := make([]interface{}, n, n) + for i := 0; i < n; i++ { + val := make(map[string]interface{}) + item := value1[i].(map[string]interface{}) + + if v, ok := item["href"]; ok { + val["href"] = v + } else { + val["href"] = nil + } + + if v, ok := item["rel"]; ok { + val["rel"] = v + } else { + val["rel"] = nil + } + + result[i] = val + } + + return result +} + +func fillReadRespMaintainWindow(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["day"]; ok { + result["day"] = v + } else { + result["day"] = nil + } + + if v, ok := value1["endTime"]; ok { + result["endTime"] = v + } else { + result["endTime"] = nil + } + + if v, ok := value1["startTime"]; ok { + result["startTime"] = v + } else { + result["startTime"] = nil + } + + return result +} + +func fillReadRespPublicEndpointStatus(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["errorMessage"]; ok { + result["errorMessage"] = v + } else { + result["errorMessage"] = nil + } + + if v, ok := value1["status"]; ok { + result["status"] = v + } else { + result["status"] = nil + } + + return result +} + +func fillReadRespTask(value interface{}) interface{} { + if value == nil { + return nil + } + + value1, ok := value.(map[string]interface{}) + if !ok { + value1 = make(map[string]interface{}) + } + result := make(map[string]interface{}) + + if v, ok := value1["description"]; ok { + result["description"] = v + } else { + result["description"] = nil + } + + if v, ok := value1["id"]; ok { + result["id"] = v + } else { + result["id"] = nil + } + + if v, ok := value1["name"]; ok { + result["name"] = v + } else { + result["name"] = nil + } + + return result +} + +func setCdmClusterV1Properties(d *schema.ResourceData, response map[string]interface{}) error { + opts := resourceCdmClusterV1UserInputParams(d) + + v, err := navigateValue(response, []string{"read", "created"}, nil) + if err != nil { + return fmt.Errorf("Error reading Cluster:created, err: %s", err) + } + if err = d.Set("created", v); err != nil { + return fmt.Errorf("Error setting Cluster:created, err: %s", err) + } + + v, _ = opts["instances"] + v, err = flattenCdmClusterV1Instances(response, nil, v) + if err != nil { + return fmt.Errorf("Error reading Cluster:instances, err: %s", err) + } + if err = d.Set("instances", v); err != nil { + return fmt.Errorf("Error setting Cluster:instances, err: %s", err) + } + + v, err = navigateValue(response, []string{"read", "isAutoOff"}, nil) + if err != nil { + return fmt.Errorf("Error reading Cluster:is_auto_off, err: %s", err) + } + if err = d.Set("is_auto_off", v); err != nil { + return fmt.Errorf("Error setting Cluster:is_auto_off, err: %s", err) + } + + v, err = navigateValue(response, []string{"read", "name"}, nil) + if err != nil { + return fmt.Errorf("Error reading Cluster:name, err: %s", err) + } + if err = d.Set("name", v); err != nil { + return fmt.Errorf("Error setting Cluster:name, err: %s", err) + } + + v, err = navigateValue(response, []string{"read", "publicEndpoint"}, nil) + if err != nil { + return fmt.Errorf("Error reading Cluster:publid_ip, err: %s", err) + } + if err = d.Set("publid_ip", v); err != nil { + return fmt.Errorf("Error setting Cluster:publid_ip, err: %s", err) + } + + v, err = navigateValue(response, []string{"read", "datastore", "version"}, nil) + if err != nil { + return fmt.Errorf("Error reading Cluster:version, err: %s", err) + } + if err = d.Set("version", v); err != nil { + return fmt.Errorf("Error setting Cluster:version, err: %s", err) + } + + return nil +} + +func flattenCdmClusterV1Instances(d interface{}, arrayIndex map[string]int, currentValue interface{}) (interface{}, error) { + result, ok := currentValue.([]interface{}) + if !ok || len(result) == 0 { + v, err := navigateValue(d, []string{"read", "instances"}, arrayIndex) + if err != nil { + return nil, err + } + n := 1 + if v1, ok := v.([]interface{}); ok { + n = len(v1) + if n < 1 { + n = 1 + } + } + result = make([]interface{}, n, n) + } + + newArrayIndex := make(map[string]int) + if arrayIndex != nil { + for k, v := range arrayIndex { + newArrayIndex[k] = v + } + } + + for i := 0; i < len(result); i++ { + newArrayIndex["read.instances"] = i + if result[i] == nil { + result[i] = make(map[string]interface{}) + } + r := result[i].(map[string]interface{}) + + v, err := navigateValue(d, []string{"read", "instances", "id"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:id, err: %s", err) + } + r["id"] = v + + v, err = navigateValue(d, []string{"read", "instances", "name"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:name, err: %s", err) + } + r["name"] = v + + v, err = navigateValue(d, []string{"read", "instances", "publicIp"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:public_ip, err: %s", err) + } + r["public_ip"] = v + + v, err = navigateValue(d, []string{"read", "instances", "role"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:role, err: %s", err) + } + r["role"] = v + + v, err = navigateValue(d, []string{"read", "instances", "trafficIp"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:traffic_ip, err: %s", err) + } + r["traffic_ip"] = v + + v, err = navigateValue(d, []string{"read", "instances", "type"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:type, err: %s", err) + } + r["type"] = v + } + + return result, nil +} diff --git a/huaweicloud/resource_huaweicloud_cdm_cluster_v1_test.go b/huaweicloud/resource_huaweicloud_cdm_cluster_v1_test.go new file mode 100644 index 0000000000..6894e3eef0 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_cdm_cluster_v1_test.go @@ -0,0 +1,125 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file at +// https://www.github.com/huaweicloud/magic-modules +// +// ---------------------------------------------------------------------------- + +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/huaweicloud/golangsdk" +) + +func TestAccCdmClusterV1_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCdmClusterV1Destroy, + Steps: []resource.TestStep{ + { + Config: testAccCdmClusterV1_basic(acctest.RandString(10)), + Check: resource.ComposeTestCheckFunc( + testAccCheckCdmClusterV1Exists(), + ), + }, + }, + }) +} + +func testAccCdmClusterV1_basic(val string) string { + return fmt.Sprintf(` +resource "huaweicloud_networking_secgroup_v2" "secgroup" { + name = "terraform_test_security_group%s" + description = "terraform security group acceptance test" +} + +resource "huaweicloud_cdm_cluster_v1" "cluster" { + availability_zone = "%s" + flavor_id = "a79fd5ae-1833-448a-88e8-3ea2b913e1f6" + name = "terraform_test_cdm_cluster%s" + security_group_id = "${huaweicloud_networking_secgroup_v2.secgroup.id}" + subnet_id = "%s" + vpc_id = "%s" + version = "1.8.5" +} + `, val, OS_AVAILABILITY_ZONE, val, OS_NETWORK_ID, OS_VPC_ID) +} + +func testAccCheckCdmClusterV1Destroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + client, err := config.sdkClient(OS_REGION_NAME, "cdm", serviceProjectLevel) + if err != nil { + return fmt.Errorf("Error creating sdk client, err=%s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "huaweicloud_cdm_cluster_v1" { + continue + } + + url, err := replaceVarsForTest(rs, "clusters/{id}") + if err != nil { + return err + } + url = client.ServiceURL(url) + + _, err = client.Get(url, nil, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if err == nil { + return fmt.Errorf("huaweicloud_cdm_cluster_v1 still exists at %s", url) + } + } + + return nil +} + +func testAccCheckCdmClusterV1Exists() resource.TestCheckFunc { + return func(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + client, err := config.sdkClient(OS_REGION_NAME, "cdm", serviceProjectLevel) + if err != nil { + return fmt.Errorf("Error creating sdk client, err=%s", err) + } + + rs, ok := s.RootModule().Resources["huaweicloud_cdm_cluster_v1.cluster"] + if !ok { + return fmt.Errorf("Error checking huaweicloud_cdm_cluster_v1.cluster exist, err=not found this resource") + } + + url, err := replaceVarsForTest(rs, "clusters/{id}") + if err != nil { + return fmt.Errorf("Error checking huaweicloud_cdm_cluster_v1.cluster exist, err=building url failed: %s", err) + } + url = client.ServiceURL(url) + + _, err = client.Get(url, nil, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": "application/json", + "X-Language": "en-us", + }}) + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + return fmt.Errorf("huaweicloud_cdm_cluster_v1.cluster is not exist") + } + return fmt.Errorf("Error checking huaweicloud_cdm_cluster_v1.cluster exist, err=send request failed: %s", err) + } + return nil + } +} diff --git a/huaweicloud/transport.go b/huaweicloud/transport.go index fd578aebb1..378081fcdf 100644 --- a/huaweicloud/transport.go +++ b/huaweicloud/transport.go @@ -68,7 +68,8 @@ func replaceVars(d *schema.ResourceData, linkTmpl string, kv map[string]string) } v, ok := d.GetOk(m) if ok { - return v.(string) + v1, _ := convertToStr(v) + return v1 } } return "" @@ -116,6 +117,56 @@ func navigateMap(d interface{}, index []string) (interface{}, error) { return d, nil } +func navigateValue(d interface{}, index []string, arrayIndex map[string]int) (interface{}, error) { + for n, i := range index { + if d == nil { + return nil, nil + } + if d1, ok := d.(map[string]interface{}); ok { + d, ok = d1[i] + if !ok { + return nil, fmt.Errorf("navigate:: '%s' may not exist", i) + } + } else { + return nil, fmt.Errorf("navigateValue:: Can not convert (%s) to map, index=%s", reflect.TypeOf(d), strings.Join(index, ".")) + } + + if arrayIndex != nil { + if j, ok := arrayIndex[strings.Join(index[:n+1], ".")]; ok { + if d == nil { + return nil, nil + } + if d2, ok := d.([]interface{}); ok { + if j >= len(d2) { + return nil, fmt.Errorf("navigate:: The index is out of array") + } + + d = d2[j] + } else { + return nil, fmt.Errorf("navigateValue:: Can not convert (%s) to array, index=%s.%v", reflect.TypeOf(d), i, j) + } + } + } + } + + return d, nil +} + +func isUserInput(d *schema.ResourceData, index []string, arrayIndex map[string]int) bool { + var r = make([]string, 0, len(index)*2) + for n, i := range index { + r = append(r, i) + + if arrayIndex != nil { + if j, ok := arrayIndex[strings.Join(index[:n+1], ".")]; ok { + r = append(r, strconv.Itoa(j)) + } + } + } + _, e := d.GetOkExists(strings.Join(r[:len(r)], ".")) + return e +} + func convertToInt(v interface{}) (interface{}, error) { // Handles the string fixed64 format if strVal, ok := v.(string); ok { @@ -124,6 +175,20 @@ func convertToInt(v interface{}) (interface{}, error) { return nil, fmt.Errorf("can not convert to integer") } +func convertToStr(v interface{}) (string, error) { + if s, ok := v.(string); ok { + return s, nil + + } else if i, ok := v.(int); ok { + return strconv.Itoa(i), nil + + } else if b, ok := v.(bool); ok { + return strconv.FormatBool(b), nil + } + + return "", fmt.Errorf("can't convert to string") +} + func waitToFinish(target, pending []string, timeout, interval time.Duration, f resource.StateRefreshFunc) (interface{}, error) { stateConf := &resource.StateChangeConf{ Target: target, diff --git a/website/docs/d/cdm_flavors_v1.html.markdown b/website/docs/d/cdm_flavors_v1.html.markdown new file mode 100644 index 0000000000..f301b9720e --- /dev/null +++ b/website/docs/d/cdm_flavors_v1.html.markdown @@ -0,0 +1,33 @@ +--- +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_cdm_flavors_v1" +sidebar_current: "docs-huaweicloud-datasource-cdm-flavors-v1" +description: |- + Get the flavor information on a HuaweiCloud cdm service. +--- + +# huaweicloud\_cdm\_flavors\_v1 + +Use this data source to get available Huaweicloud cdm flavors. + +## Example Usage + +```hcl +data "huaweicloud_cdm_flavors_v1" "flavor" { +} +``` + +## Attributes Reference + +The following attributes are exported: + +* `version` - + The version of the flavor. + +* `flavors` - + Indicates the flavors information. Structure is documented below. + +The `flavors` block contains: + +* `name` - The name of the cdm flavor. +* `id` - The id of the cdm flavor. diff --git a/website/docs/r/cdm_cluster_v1.html.markdown b/website/docs/r/cdm_cluster_v1.html.markdown new file mode 100644 index 0000000000..6f43c90bc8 --- /dev/null +++ b/website/docs/r/cdm_cluster_v1.html.markdown @@ -0,0 +1,150 @@ +--- +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_cdm_cluster_v1" +sidebar_current: "docs-huaweicloud-resource-cdm-cluster-v1" +description: |- + cdm cluster management +--- + +# huaweicloud\_cdm\_cluster\_v1 + +cdm cluster management + +## Example Usage + +### create a cdm cluster + +```hcl +resource "opentelekomcloud_networking_secgroup_v2" "secgroup" { + name = "terraform_test_security_group" + description = "terraform security group acceptance test" +} + +resource "huaweicloud_cdm_cluster_v1" "cluster" { + availability_zone = "{{ availability_zone }}" + flavor_id = "{{ flavor_id }}" + name = "terraform_test_cdm_cluster" + security_group_id = "${opentelekomcloud_networking_secgroup_v2.secgroup.id}" + subnet_id = "{{ network_id }}" + vpc_id = "{{ vpc_id }}" + version = "{{ version }}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `availability_zone` - + (Required) + + Available zone. Changing this parameter will create a new resource. + +* `flavor_id` - + (Required) + + Flavor id. Changing this parameter will create a new resource. + +* `name` - + (Required) + + Cluster name. Changing this parameter will create a new resource. + +* `security_group_id` - + (Required) + + Security group ID. Changing this parameter will create a new resource. + +* `subnet_id` - + (Required) + + Subnet ID. Changing this parameter will create a new resource. + +* `version` - + (Required) + + Cluster version. Changing this parameter will create a new resource. + +* `vpc_id` - + (Required) + + VPC ID. Changing this parameter will create a new resource. + +- - - + +* `email` - + (Optional) + + Notification email addresses. The max number is 5. Changing this parameter will create a new resource. + +* `enterprise_project_id` - + (Optional) + + The enterprise project id. Changing this parameter will create a new resource. + +* `is_auto_off` - + (Optional) + + Whether to automatically shut down. Changing this parameter will create a new resource. + +* `phone_num` - + (Optional) + + Notification phone numbers. The max number is 5. Changing this parameter will create a new resource. + +* `schedule_boot_time` - + (Optional) + + Timed boot time. Changing this parameter will create a new resource. + +* `schedule_off_time` - + (Optional) + + Timed shutdown time. Changing this parameter will create a new resource. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `created` - + + Create time. + +* `instances` - + + Instance list. Structure is documented below. + +* `publid_ip` - + + Public ip. + +The `instances` block contains: + +* `id` - + + Instance ID. + +* `name` - + + Instance name. + +* `public_ip` - + + Public IP. + +* `role` - + + Role. + +* `traffic_ip` - + + Traffic IP. + +* `type` - + + Instance type. + +## Timeouts + +This resource provides the following timeouts configuration options: +- `create` - Default is 30 minute. diff --git a/website/huaweicloud.erb b/website/huaweicloud.erb index 1b2b391787..74501044af 100644 --- a/website/huaweicloud.erb +++ b/website/huaweicloud.erb @@ -102,6 +102,9 @@ > huaweicloud_dcs_maintainwindow_v1 + > + huaweicloud_cdm_flavors_v1 + @@ -506,6 +509,15 @@ + + > + CDM Resources + + <% end %> From 2970dd6b592e7cad5bc57c7eb6c01d45273e49c5 Mon Sep 17 00:00:00 2001 From: zengchen1024 Date: Tue, 21 May 2019 14:35:17 +0800 Subject: [PATCH 3/3] fix bugs --- .../resource_huaweicloud_cdm_cluster_v1.go | 132 +++++++++++------- website/docs/r/cdm_cluster_v1.html.markdown | 26 +--- 2 files changed, 87 insertions(+), 71 deletions(-) diff --git a/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go b/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go index b06f4e727b..7483e63c67 100644 --- a/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go +++ b/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go @@ -234,7 +234,7 @@ func resourceCdmClusterV1Read(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } - res["read"] = fillReadRespBody(v) + res["read"] = fillCdmClusterV1ReadRespBody(v) return setCdmClusterV1Properties(d, res) } @@ -687,7 +687,7 @@ func sendCdmClusterV1ReadRequest(d *schema.ResourceData, client *golangsdk.Servi return r.Body, nil } -func fillReadRespBody(body interface{}) interface{} { +func fillCdmClusterV1ReadRespBody(body interface{}) interface{} { result := make(map[string]interface{}) val, ok := body.(map[string]interface{}) if !ok { @@ -731,13 +731,13 @@ func fillReadRespBody(body interface{}) interface{} { } if v, ok := val["customerConfig"]; ok { - result["customerConfig"] = fillReadRespCustomerConfig(v) + result["customerConfig"] = fillCdmClusterV1ReadRespCustomerConfig(v) } else { result["customerConfig"] = nil } if v, ok := val["datastore"]; ok { - result["datastore"] = fillReadRespDatastore(v) + result["datastore"] = fillCdmClusterV1ReadRespDatastore(v) } else { result["datastore"] = nil } @@ -773,7 +773,7 @@ func fillReadRespBody(body interface{}) interface{} { } if v, ok := val["instances"]; ok { - result["instances"] = fillReadRespInstances(v) + result["instances"] = fillCdmClusterV1ReadRespInstances(v) } else { result["instances"] = nil } @@ -797,13 +797,13 @@ func fillReadRespBody(body interface{}) interface{} { } if v, ok := val["links"]; ok { - result["links"] = fillReadRespLinks(v) + result["links"] = fillCdmClusterV1ReadRespLinks(v) } else { result["links"] = nil } if v, ok := val["maintainWindow"]; ok { - result["maintainWindow"] = fillReadRespMaintainWindow(v) + result["maintainWindow"] = fillCdmClusterV1ReadRespMaintainWindow(v) } else { result["maintainWindow"] = nil } @@ -827,7 +827,7 @@ func fillReadRespBody(body interface{}) interface{} { } if v, ok := val["publicEndpointStatus"]; ok { - result["publicEndpointStatus"] = fillReadRespPublicEndpointStatus(v) + result["publicEndpointStatus"] = fillCdmClusterV1ReadRespPublicEndpointStatus(v) } else { result["publicEndpointStatus"] = nil } @@ -851,7 +851,7 @@ func fillReadRespBody(body interface{}) interface{} { } if v, ok := val["task"]; ok { - result["task"] = fillReadRespTask(v) + result["task"] = fillCdmClusterV1ReadRespTask(v) } else { result["task"] = nil } @@ -865,7 +865,7 @@ func fillReadRespBody(body interface{}) interface{} { return result } -func fillReadRespCustomerConfig(value interface{}) interface{} { +func fillCdmClusterV1ReadRespCustomerConfig(value interface{}) interface{} { if value == nil { return nil } @@ -909,7 +909,7 @@ func fillReadRespCustomerConfig(value interface{}) interface{} { return result } -func fillReadRespDatastore(value interface{}) interface{} { +func fillCdmClusterV1ReadRespDatastore(value interface{}) interface{} { if value == nil { return nil } @@ -935,7 +935,7 @@ func fillReadRespDatastore(value interface{}) interface{} { return result } -func fillReadRespInstances(value interface{}) interface{} { +func fillCdmClusterV1ReadRespInstances(value interface{}) interface{} { if value == nil { return nil } @@ -958,7 +958,7 @@ func fillReadRespInstances(value interface{}) interface{} { } if v, ok := item["flavor"]; ok { - val["flavor"] = fillReadRespInstancesFlavor(v) + val["flavor"] = fillCdmClusterV1ReadRespInstancesFlavor(v) } else { val["flavor"] = nil } @@ -982,7 +982,7 @@ func fillReadRespInstances(value interface{}) interface{} { } if v, ok := item["links_2"]; ok { - val["links_2"] = fillReadRespInstancesLinks2(v) + val["links_2"] = fillCdmClusterV1ReadRespInstancesLinks2(v) } else { val["links_2"] = nil } @@ -1042,7 +1042,7 @@ func fillReadRespInstances(value interface{}) interface{} { } if v, ok := item["volume"]; ok { - val["volume"] = fillReadRespInstancesVolume(v) + val["volume"] = fillCdmClusterV1ReadRespInstancesVolume(v) } else { val["volume"] = nil } @@ -1053,7 +1053,7 @@ func fillReadRespInstances(value interface{}) interface{} { return result } -func fillReadRespInstancesFlavor(value interface{}) interface{} { +func fillCdmClusterV1ReadRespInstancesFlavor(value interface{}) interface{} { if value == nil { return nil } @@ -1071,7 +1071,7 @@ func fillReadRespInstancesFlavor(value interface{}) interface{} { } if v, ok := value1["links_1"]; ok { - result["links_1"] = fillReadRespInstancesFlavorLinks1(v) + result["links_1"] = fillCdmClusterV1ReadRespInstancesFlavorLinks1(v) } else { result["links_1"] = nil } @@ -1079,7 +1079,7 @@ func fillReadRespInstancesFlavor(value interface{}) interface{} { return result } -func fillReadRespInstancesFlavorLinks1(value interface{}) interface{} { +func fillCdmClusterV1ReadRespInstancesFlavorLinks1(value interface{}) interface{} { if value == nil { return nil } @@ -1113,7 +1113,7 @@ func fillReadRespInstancesFlavorLinks1(value interface{}) interface{} { return result } -func fillReadRespInstancesLinks2(value interface{}) interface{} { +func fillCdmClusterV1ReadRespInstancesLinks2(value interface{}) interface{} { if value == nil { return nil } @@ -1147,7 +1147,7 @@ func fillReadRespInstancesLinks2(value interface{}) interface{} { return result } -func fillReadRespInstancesVolume(value interface{}) interface{} { +func fillCdmClusterV1ReadRespInstancesVolume(value interface{}) interface{} { if value == nil { return nil } @@ -1173,7 +1173,7 @@ func fillReadRespInstancesVolume(value interface{}) interface{} { return result } -func fillReadRespLinks(value interface{}) interface{} { +func fillCdmClusterV1ReadRespLinks(value interface{}) interface{} { if value == nil { return nil } @@ -1207,7 +1207,7 @@ func fillReadRespLinks(value interface{}) interface{} { return result } -func fillReadRespMaintainWindow(value interface{}) interface{} { +func fillCdmClusterV1ReadRespMaintainWindow(value interface{}) interface{} { if value == nil { return nil } @@ -1239,7 +1239,7 @@ func fillReadRespMaintainWindow(value interface{}) interface{} { return result } -func fillReadRespPublicEndpointStatus(value interface{}) interface{} { +func fillCdmClusterV1ReadRespPublicEndpointStatus(value interface{}) interface{} { if value == nil { return nil } @@ -1265,7 +1265,7 @@ func fillReadRespPublicEndpointStatus(value interface{}) interface{} { return result } -func fillReadRespTask(value interface{}) interface{} { +func fillCdmClusterV1ReadRespTask(value interface{}) interface{} { if value == nil { return nil } @@ -1304,8 +1304,10 @@ func setCdmClusterV1Properties(d *schema.ResourceData, response map[string]inter if err != nil { return fmt.Errorf("Error reading Cluster:created, err: %s", err) } - if err = d.Set("created", v); err != nil { - return fmt.Errorf("Error setting Cluster:created, err: %s", err) + if v != nil { + if err = d.Set("created", v); err != nil { + return fmt.Errorf("Error setting Cluster:created, err: %s", err) + } } v, _ = opts["instances"] @@ -1313,46 +1315,57 @@ func setCdmClusterV1Properties(d *schema.ResourceData, response map[string]inter if err != nil { return fmt.Errorf("Error reading Cluster:instances, err: %s", err) } - if err = d.Set("instances", v); err != nil { - return fmt.Errorf("Error setting Cluster:instances, err: %s", err) + if v != nil { + if err = d.Set("instances", v); err != nil { + return fmt.Errorf("Error setting Cluster:instances, err: %s", err) + } } v, err = navigateValue(response, []string{"read", "isAutoOff"}, nil) if err != nil { return fmt.Errorf("Error reading Cluster:is_auto_off, err: %s", err) } - if err = d.Set("is_auto_off", v); err != nil { - return fmt.Errorf("Error setting Cluster:is_auto_off, err: %s", err) + if v != nil { + if err = d.Set("is_auto_off", v); err != nil { + return fmt.Errorf("Error setting Cluster:is_auto_off, err: %s", err) + } } v, err = navigateValue(response, []string{"read", "name"}, nil) if err != nil { return fmt.Errorf("Error reading Cluster:name, err: %s", err) } - if err = d.Set("name", v); err != nil { - return fmt.Errorf("Error setting Cluster:name, err: %s", err) + if v != nil { + if err = d.Set("name", v); err != nil { + return fmt.Errorf("Error setting Cluster:name, err: %s", err) + } } v, err = navigateValue(response, []string{"read", "publicEndpoint"}, nil) if err != nil { return fmt.Errorf("Error reading Cluster:publid_ip, err: %s", err) } - if err = d.Set("publid_ip", v); err != nil { - return fmt.Errorf("Error setting Cluster:publid_ip, err: %s", err) + if v != nil { + if err = d.Set("publid_ip", v); err != nil { + return fmt.Errorf("Error setting Cluster:publid_ip, err: %s", err) + } } v, err = navigateValue(response, []string{"read", "datastore", "version"}, nil) if err != nil { return fmt.Errorf("Error reading Cluster:version, err: %s", err) } - if err = d.Set("version", v); err != nil { - return fmt.Errorf("Error setting Cluster:version, err: %s", err) + if v != nil { + if err = d.Set("version", v); err != nil { + return fmt.Errorf("Error setting Cluster:version, err: %s", err) + } } return nil } func flattenCdmClusterV1Instances(d interface{}, arrayIndex map[string]int, currentValue interface{}) (interface{}, error) { + n := 0 result, ok := currentValue.([]interface{}) if !ok || len(result) == 0 { v, err := navigateValue(d, []string{"read", "instances"}, arrayIndex) @@ -1366,7 +1379,9 @@ func flattenCdmClusterV1Instances(d interface{}, arrayIndex map[string]int, curr n = 1 } } - result = make([]interface{}, n, n) + result = make([]interface{}, 0, n) + } else { + n = len(result) } newArrayIndex := make(map[string]int) @@ -1376,48 +1391,71 @@ func flattenCdmClusterV1Instances(d interface{}, arrayIndex map[string]int, curr } } - for i := 0; i < len(result); i++ { + for i := 0; i < n; i++ { newArrayIndex["read.instances"] = i - if result[i] == nil { - result[i] = make(map[string]interface{}) + + var r map[string]interface{} + if len(result) >= (i+1) && result[i] != nil { + r = result[i].(map[string]interface{}) + } else { + r = make(map[string]interface{}) } - r := result[i].(map[string]interface{}) v, err := navigateValue(d, []string{"read", "instances", "id"}, newArrayIndex) if err != nil { return nil, fmt.Errorf("Error reading Cluster:id, err: %s", err) } - r["id"] = v + if v != nil { + r["id"] = v + } v, err = navigateValue(d, []string{"read", "instances", "name"}, newArrayIndex) if err != nil { return nil, fmt.Errorf("Error reading Cluster:name, err: %s", err) } - r["name"] = v + if v != nil { + r["name"] = v + } v, err = navigateValue(d, []string{"read", "instances", "publicIp"}, newArrayIndex) if err != nil { return nil, fmt.Errorf("Error reading Cluster:public_ip, err: %s", err) } - r["public_ip"] = v + if v != nil { + r["public_ip"] = v + } v, err = navigateValue(d, []string{"read", "instances", "role"}, newArrayIndex) if err != nil { return nil, fmt.Errorf("Error reading Cluster:role, err: %s", err) } - r["role"] = v + if v != nil { + r["role"] = v + } v, err = navigateValue(d, []string{"read", "instances", "trafficIp"}, newArrayIndex) if err != nil { return nil, fmt.Errorf("Error reading Cluster:traffic_ip, err: %s", err) } - r["traffic_ip"] = v + if v != nil { + r["traffic_ip"] = v + } v, err = navigateValue(d, []string{"read", "instances", "type"}, newArrayIndex) if err != nil { return nil, fmt.Errorf("Error reading Cluster:type, err: %s", err) } - r["type"] = v + if v != nil { + r["type"] = v + } + + if len(r) != 0 { + if len(result) >= (i + 1) { + result[i] = r + } else { + result = append(result, r) + } + } } return result, nil diff --git a/website/docs/r/cdm_cluster_v1.html.markdown b/website/docs/r/cdm_cluster_v1.html.markdown index 6f43c90bc8..ca4d6b165c 100644 --- a/website/docs/r/cdm_cluster_v1.html.markdown +++ b/website/docs/r/cdm_cluster_v1.html.markdown @@ -15,7 +15,7 @@ cdm cluster management ### create a cdm cluster ```hcl -resource "opentelekomcloud_networking_secgroup_v2" "secgroup" { +resource "huaweicloud_networking_secgroup_v2" "secgroup" { name = "terraform_test_security_group" description = "terraform security group acceptance test" } @@ -24,7 +24,7 @@ resource "huaweicloud_cdm_cluster_v1" "cluster" { availability_zone = "{{ availability_zone }}" flavor_id = "{{ flavor_id }}" name = "terraform_test_cdm_cluster" - security_group_id = "${opentelekomcloud_networking_secgroup_v2.secgroup.id}" + security_group_id = "${huaweicloud_networking_secgroup_v2.secgroup.id}" subnet_id = "{{ network_id }}" vpc_id = "{{ vpc_id }}" version = "{{ version }}" @@ -37,69 +37,56 @@ The following arguments are supported: * `availability_zone` - (Required) - Available zone. Changing this parameter will create a new resource. * `flavor_id` - (Required) - Flavor id. Changing this parameter will create a new resource. * `name` - (Required) - Cluster name. Changing this parameter will create a new resource. * `security_group_id` - (Required) - Security group ID. Changing this parameter will create a new resource. * `subnet_id` - (Required) - Subnet ID. Changing this parameter will create a new resource. * `version` - (Required) - Cluster version. Changing this parameter will create a new resource. * `vpc_id` - (Required) - VPC ID. Changing this parameter will create a new resource. - - - * `email` - (Optional) - Notification email addresses. The max number is 5. Changing this parameter will create a new resource. * `enterprise_project_id` - (Optional) - The enterprise project id. Changing this parameter will create a new resource. * `is_auto_off` - (Optional) - Whether to automatically shut down. Changing this parameter will create a new resource. * `phone_num` - (Optional) - Notification phone numbers. The max number is 5. Changing this parameter will create a new resource. * `schedule_boot_time` - (Optional) - Timed boot time. Changing this parameter will create a new resource. * `schedule_off_time` - (Optional) - Timed shutdown time. Changing this parameter will create a new resource. ## Attributes Reference @@ -107,41 +94,32 @@ The following arguments are supported: In addition to the arguments listed above, the following computed attributes are exported: * `created` - - Create time. * `instances` - - Instance list. Structure is documented below. * `publid_ip` - - Public ip. The `instances` block contains: * `id` - - Instance ID. * `name` - - Instance name. * `public_ip` - - Public IP. * `role` - - Role. * `traffic_ip` - - Traffic IP. * `type` - - Instance type. ## Timeouts