diff --git a/docs/data-sources/compute_flavors.md b/docs/data-sources/compute_flavors.md new file mode 100644 index 0000000000..7e74ab4004 --- /dev/null +++ b/docs/data-sources/compute_flavors.md @@ -0,0 +1,44 @@ +--- +subcategory: "Elastic Cloud Server (ECS)" +--- + +# huaweicloud\_compute\_flavors + +Use this data source to get the ID of the available Compute Flavors. + +## Example Usage + +```hcl +data "huaweicloud_compute_flavors" "flavors" { + performance_type = "normal" + cpu_core_count = 2 + memory_size = 4096 +} + +# Create ECS instance with the first matched flavor + +resource "huaweicloud_compute_instance" "instance" { + flavor_id = data.huaweicloud_compute_flavors.flavors.ids[0] + + # Other properties... +} +``` + +## Argument Reference + +* `availability_zone` - (Optional) Specifies the AZ name. + +* `performance_type` - (Optional) Specifies the ECS flavor type. + +* `generation` - (Optional) Specifies the generation of an ECS type. + +* `cpu_core_count` - (Optional) Specifies the number of vCPUs in the ECS flavor. + +* `memory_size` - (Optional) Specifies the memory size(MB) in the ECS flavor. + + +## Attributes Reference + +`id` is set to the ID of the found flavors. In addition, the following attributes are exported: + +* `ids` - A list of flavor IDs. diff --git a/huaweicloud/data_source_huaweicloud_compute_flavors.go b/huaweicloud/data_source_huaweicloud_compute_flavors.go new file mode 100644 index 0000000000..93337d29b7 --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_compute_flavors.go @@ -0,0 +1,107 @@ +package huaweicloud + +import ( + "fmt" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors" +) + +func DataSourceEcsFlavors() *schema.Resource { + return &schema.Resource{ + Read: dataSourceEcsFlavorsRead, + + Schema: map[string]*schema.Schema{ + "availability_zone": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "performance_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "generation": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "cpu_core_count": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "memory_size": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceEcsFlavorsRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + ecsClient, err := config.computeV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud ECS client: %s", err) + } + + listOpts := &flavors.ListOpts{ + AvailabilityZone: d.Get("availability_zone").(string), + } + + pages, err := flavors.List(ecsClient, listOpts).AllPages() + if err != nil { + return err + } + + allFlavors, err := flavors.ExtractFlavors(pages) + if err != nil { + return fmt.Errorf("Unable to retrieve flavors: %s ", err) + } + + cpu := d.Get("cpu_core_count").(int) + mem := int64(d.Get("memory_size").(int)) + pType := d.Get("performance_type").(string) + gen := d.Get("generation").(string) + + var ids []string + for _, flavor := range allFlavors { + vCpu, _ := strconv.Atoi(flavor.Vcpus) + if cpu > 0 && vCpu != cpu { + continue + } + + if mem > 0 && flavor.Ram != mem { + continue + } + + if pType != "" && flavor.OsExtraSpecs.PerformanceType != pType { + continue + } + + if gen != "" && flavor.OsExtraSpecs.Generation != gen { + continue + } + + ids = append(ids, flavor.ID) + } + + if len(ids) < 1 { + return fmt.Errorf("Your query returned no results. " + + "Please change your search criteria and try again.") + } + + d.SetId(dataResourceIdHash(ids)) + d.Set("ids", ids) + + return nil +} diff --git a/huaweicloud/data_source_huaweicloud_compute_flavors_test.go b/huaweicloud/data_source_huaweicloud_compute_flavors_test.go new file mode 100644 index 0000000000..e8ecca65ce --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_compute_flavors_test.go @@ -0,0 +1,47 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccEcsFlavorsDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEcsFlavorsDataSource_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckEcsFlavorDataSourceID("data.huaweicloud_compute_flavors.this"), + ), + }, + }, + }) +} + +func testAccCheckEcsFlavorDataSourceID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find compute flavors data source: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Compute Flavors data source ID not set") + } + + return nil + } +} + +const testAccEcsFlavorsDataSource_basic = ` +data "huaweicloud_compute_flavors" "this" { + performance_type = "normal" + cpu_core_count = 2 + memory_size = 4096 +} +` diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 8c84d5c0de..888966cfca 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -195,6 +195,7 @@ func Provider() terraform.ResourceProvider { "huaweicloud_cce_cluster": dataSourceCCEClusterV3(), "huaweicloud_cce_node": dataSourceCCENodeV3(), "huaweicloud_cdm_flavors": dataSourceCdmFlavorV1(), + "huaweicloud_compute_flavors": DataSourceEcsFlavors(), "huaweicloud_csbs_backup": dataSourceCSBSBackupV1(), "huaweicloud_csbs_backup_policy": dataSourceCSBSBackupPolicyV1(), "huaweicloud_cts_tracker": dataSourceCTSTrackerV1(), diff --git a/huaweicloud/util.go b/huaweicloud/util.go index b5afd878b8..a6ddbd50d3 100644 --- a/huaweicloud/util.go +++ b/huaweicloud/util.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/huaweicloud/golangsdk" @@ -185,3 +186,14 @@ func jsonMarshal(t interface{}) ([]byte, error) { err := enc.Encode(t) return buffer.Bytes(), err } + +// Generates a hash for the set hash function used by the ID +func dataResourceIdHash(ids []string) string { + var buf bytes.Buffer + + for _, id := range ids { + buf.WriteString(fmt.Sprintf("%s-", id)) + } + + return fmt.Sprintf("%d", hashcode.String(buf.String())) +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/requests.go new file mode 100644 index 0000000000..fe2229982f --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/requests.go @@ -0,0 +1,43 @@ +package flavors + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToFlavorListMap() (string, error) +} + +//ListOpts allows the filtering and sorting of paginated collections through the API. +type ListOpts struct { + // Specifies the AZ name. + AvailabilityZone string `q:"availability_zone"` +} + +// ToFlavorListMap formats a ListOpts into a query string. +func (opts ListOpts) ToFlavorListMap() (string, error) { + s, err := golangsdk.BuildQueryString(opts) + if err != nil { + return "", err + } + return s.String(), err +} + +// List returns a Pager which allows you to iterate over a collection of +// flavors. +func List(c *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := listURL(c) + if opts != nil { + queryString, err := opts.ToFlavorListMap() + if err != nil { + return pagination.Pager{Err: err} + } + url += queryString + } + return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { + return FlavorsPage{pagination.LinkedPageBase{PageResult: r}} + }) +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/results.go new file mode 100644 index 0000000000..6e86776c7f --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/results.go @@ -0,0 +1,108 @@ +package flavors + +import ( + "github.com/huaweicloud/golangsdk/pagination" +) + +type Flavor struct { + // Specifies the ID of ECS specifications. + ID string `json:"id"` + + // Specifies the name of the ECS specifications. + Name string `json:"name"` + + // Specifies the number of CPU cores in the ECS specifications. + Vcpus string `json:"vcpus"` + + // Specifies the memory size (MB) in the ECS specifications. + Ram int64 `json:"ram"` + + // Specifies the system disk size in the ECS specifications. + // The value 0 indicates that the disk size is not limited. + Disk string `json:"disk"` + + // Specifies shortcut links for ECS flavors. + Links []Link `json:"links"` + + // Specifies extended ECS specifications. + OsExtraSpecs OsExtraSpecs `json:"os_extra_specs"` + + // Reserved + Swap string `json:"swap"` + + // Reserved + FlvEphemeral int64 `json:"OS-FLV-EXT-DATA:ephemeral"` + + // Reserved + FlvDisabled bool `json:"OS-FLV-DISABLED:disabled"` + + // Reserved + RxtxFactor int64 `json:"rxtx_factor"` + + // Reserved + RxtxQuota string `json:"rxtx_quota"` + + // Reserved + RxtxCap string `json:"rxtx_cap"` + + // Reserved + AccessIsPublic bool `json:"os-flavor-access:is_public"` +} + +type Link struct { + // Specifies the shortcut link marker name. + Rel string `json:"rel"` + + // Provides the corresponding shortcut link. + Href string `json:"href"` + + // Specifies the shortcut link type. + Type string `json:"type"` +} + +type OsExtraSpecs struct { + // Specifies the ECS specifications types + PerformanceType string `json:"ecs:performancetype"` + + // Specifies the resource type. + ResourceType string `json:"resource_type"` + + // Specifies the generation of an ECS type + Generation string `json:"ecs:generation"` + + // Specifies a virtualization type + VirtualizationEnvTypes string `json:"ecs:virtualization_env_types"` + + // Indicates whether the GPU is passthrough. + PciPassthroughEnableGpu string `json:"pci_passthrough:enable_gpu"` + + // Indicates the technology used on the G1 and G2 ECSs, + // including GPU virtualization and GPU passthrough. + PciPassthroughGpuSpecs string `json:"pci_passthrough:gpu_specs"` + + // Indicates the model and quantity of passthrough-enabled GPUs on P1 ECSs. + PciPassthroughAlias string `json:"pci_passthrough:alias"` +} + +// FlavorsPage is the page returned by a pager when traversing over a +// collection of flavor. +type FlavorsPage struct { + pagination.LinkedPageBase +} + +// IsEmpty checks whether a FlavorsPage struct is empty. +func (r FlavorsPage) IsEmpty() (bool, error) { + is, err := ExtractFlavors(r) + return len(is) == 0, err +} + +// ExtractFlavors accepts a Page struct, specifically a FlavorsPage struct, +// and extracts the elements into a slice of flavor structs. In other words, +// a generic collection is mapped into a relevant slice. +func ExtractFlavors(r pagination.Page) ([]Flavor, error) { + var s struct { + Flavors []Flavor `json:"flavors"` + } + err := (r.(FlavorsPage)).ExtractInto(&s) + return s.Flavors, err +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/urls.go new file mode 100644 index 0000000000..a565d625bc --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors/urls.go @@ -0,0 +1,7 @@ +package flavors + +import "github.com/huaweicloud/golangsdk" + +func listURL(sc *golangsdk.ServiceClient) string { + return sc.ServiceURL("cloudservers", "flavors") +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0aa3f9f6a3..1958cb2f85 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -247,6 +247,7 @@ github.com/huaweicloud/golangsdk/openstack/dns/v2/zones github.com/huaweicloud/golangsdk/openstack/ecs/v1/auto_recovery github.com/huaweicloud/golangsdk/openstack/ecs/v1/block_devices github.com/huaweicloud/golangsdk/openstack/ecs/v1/cloudservers +github.com/huaweicloud/golangsdk/openstack/ecs/v1/flavors github.com/huaweicloud/golangsdk/openstack/evs/v2/snapshots github.com/huaweicloud/golangsdk/openstack/evs/v2/tags github.com/huaweicloud/golangsdk/openstack/evs/v3/volumes