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/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..7483e63c67 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_cdm_cluster_v1.go @@ -0,0 +1,1462 @@ +// ---------------------------------------------------------------------------- +// +// *** 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"] = fillCdmClusterV1ReadRespBody(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 fillCdmClusterV1ReadRespBody(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"] = fillCdmClusterV1ReadRespCustomerConfig(v) + } else { + result["customerConfig"] = nil + } + + if v, ok := val["datastore"]; ok { + result["datastore"] = fillCdmClusterV1ReadRespDatastore(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"] = fillCdmClusterV1ReadRespInstances(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"] = fillCdmClusterV1ReadRespLinks(v) + } else { + result["links"] = nil + } + + if v, ok := val["maintainWindow"]; ok { + result["maintainWindow"] = fillCdmClusterV1ReadRespMaintainWindow(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"] = fillCdmClusterV1ReadRespPublicEndpointStatus(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"] = fillCdmClusterV1ReadRespTask(v) + } else { + result["task"] = nil + } + + if v, ok := val["updated"]; ok { + result["updated"] = v + } else { + result["updated"] = nil + } + + return result +} + +func fillCdmClusterV1ReadRespCustomerConfig(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 fillCdmClusterV1ReadRespDatastore(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 fillCdmClusterV1ReadRespInstances(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"] = fillCdmClusterV1ReadRespInstancesFlavor(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"] = fillCdmClusterV1ReadRespInstancesLinks2(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"] = fillCdmClusterV1ReadRespInstancesVolume(v) + } else { + val["volume"] = nil + } + + result[i] = val + } + + return result +} + +func fillCdmClusterV1ReadRespInstancesFlavor(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"] = fillCdmClusterV1ReadRespInstancesFlavorLinks1(v) + } else { + result["links_1"] = nil + } + + return result +} + +func fillCdmClusterV1ReadRespInstancesFlavorLinks1(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 fillCdmClusterV1ReadRespInstancesLinks2(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 fillCdmClusterV1ReadRespInstancesVolume(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 fillCdmClusterV1ReadRespLinks(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 fillCdmClusterV1ReadRespMaintainWindow(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 fillCdmClusterV1ReadRespPublicEndpointStatus(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 fillCdmClusterV1ReadRespTask(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 v != nil { + 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 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 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 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 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 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) + 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{}, 0, n) + } else { + n = len(result) + } + + newArrayIndex := make(map[string]int) + if arrayIndex != nil { + for k, v := range arrayIndex { + newArrayIndex[k] = v + } + } + + for i := 0; i < n; i++ { + newArrayIndex["read.instances"] = i + + 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{}) + } + + v, err := navigateValue(d, []string{"read", "instances", "id"}, newArrayIndex) + if err != nil { + return nil, fmt.Errorf("Error reading Cluster:id, err: %s", err) + } + 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) + } + 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) + } + 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) + } + 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) + } + 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) + } + 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/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/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) } 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..ca4d6b165c --- /dev/null +++ b/website/docs/r/cdm_cluster_v1.html.markdown @@ -0,0 +1,128 @@ +--- +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 "huaweicloud_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 = "${huaweicloud_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 @@