diff --git a/docs/data-sources/servers.md b/docs/data-sources/servers.md new file mode 100644 index 000000000..eac3f419a --- /dev/null +++ b/docs/data-sources/servers.md @@ -0,0 +1,47 @@ +# Data Source: ncloud_servers + +Use this data source to get multiple `ncloud_server` ids + +## Example Usage + +#### Basic usage + +```hcl +data "ncloud_servers" "servers" { + ids = [ncloud_server.example1.id, ncloud_server.example2.id] +} +``` + +#### Usage of using filter + +```hcl +data "ncloud_servers" "servers" { + filter { + name = "subnet_no" + values = [ncloud_subnet.example1.id, ncloud_subnet.example2.id] + } +} +``` + +#### Usage of `ncloud_servers` data source in `ncloud_nas_volume` + +```hcl +data "ncloud_servers" "servers" { + ids = [ncloud_server.example1.id, ncloud_server.example2.id] +} + +resource "ncloud_nas_volume" "vol" { + volume_name_postfix = "vol" + volume_size = "500" + volume_allotment_protocol_type = "NFS" + server_instance_no_list = data.ncloud_servers.servers.ids +} +``` + +The following arguments are supported: + +* `ids` - (Optional) The set of ID of the Server instances. +* `filter` - (Optional) Custom filter block as described below. + * `name` - (Required) The name of the field to filter by + * `values` - (Required) Set of values that are accepted for the given field. + * `regex` - (Optional) is `values` treated as a regular expression. diff --git a/ncloud/data_source_ncloud_servers.go b/ncloud/data_source_ncloud_servers.go new file mode 100644 index 000000000..a8d889419 --- /dev/null +++ b/ncloud/data_source_ncloud_servers.go @@ -0,0 +1,85 @@ +package ncloud + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func init() { + RegisterDataSource("ncloud_servers", dataSourceNcloudServers()) +} + +func dataSourceNcloudServers() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNcloudServersRead, + Schema: map[string]*schema.Schema{ + "ids": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "filter": dataSourceFiltersSchema(), + }, + } +} + +func dataSourceNcloudServersRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*ProviderConfig) + + instances, err := getServerList(d, config) + if err != nil { + return err + } + + if len(instances) < 1 { + return fmt.Errorf("no results. there is no available server resource") + } + + if values, ok := d.GetOk("ids"); ok { + return readServersIDs(d, values.(*schema.Set).List(), instances) + } + + resources := ConvertToArrayMap(instances) + if f, ok := d.GetOk("filter"); ok { + resources = ApplyFilters(f.(*schema.Set), resources, dataSourceNcloudServer().Schema) + } + + if len(resources) == 0 { + return fmt.Errorf("no results with filter. there is no available server resource") + } + + var ids []string + for _, r := range resources { + for k, v := range r { + if k == "instance_no" { + ids = append(ids, v.(string)) + } + } + } + + d.SetId(dataResourceIdHash(ids)) + d.Set("ids", ids) + return nil +} + +func readServersIDs(d *schema.ResourceData, values []interface{}, serverInstances []*ServerInstance) error { + var ids []string + for _, id := range values { + for _, s := range serverInstances { + if *s.ServerInstanceNo == id.(string) { + ids = append(ids, id.(string)) + break + } + } + } + + if len(values) != len(ids) { + return fmt.Errorf("invalid server id specified") + } + + d.SetId(dataResourceIdHash(ids)) + d.Set("ids", ids) + return nil +} diff --git a/ncloud/data_source_ncloud_servers_test.go b/ncloud/data_source_ncloud_servers_test.go new file mode 100644 index 000000000..3f5cd5ba1 --- /dev/null +++ b/ncloud/data_source_ncloud_servers_test.go @@ -0,0 +1,144 @@ +package ncloud + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const ( + dataName = "data.ncloud_servers.by_id" + dataName2 = "data.ncloud_servers.by_filter" + serverName = "ncloud_server.test" +) + +func TestAccDataSourceNcloudServers_vpc_basic(t *testing.T) { + testServerName := getTestServerName() + testServerName2 := getTestServerName() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceServersVpcConfig(testServerName, testServerName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckDataSourceID(dataName), + resource.TestMatchResourceAttr(dataName, "id", regexp.MustCompile(`^\d+$`)), + resource.TestCheckResourceAttr(dataName, "ids.#", "2"), + testAccCheckDataSourceID(dataName2), + resource.TestCheckResourceAttr(dataName2, "ids.#", "1"), + resource.TestCheckResourceAttrPair(dataName2, "ids.0", serverName, "id"), + ), + }, + }, + }) +} + +func TestAccDataSourceNcloudServers_classic_basic(t *testing.T) { + testServerName := getTestServerName() + testServerName2 := getTestServerName() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccClassicProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceServersClassicConfig(testServerName, testServerName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckDataSourceID(dataName), + resource.TestMatchResourceAttr(dataName, "id", regexp.MustCompile(`^\d+$`)), + resource.TestCheckResourceAttr(dataName, "ids.#", "2"), + testAccCheckDataSourceID(dataName2), + resource.TestCheckResourceAttr(dataName2, "ids.#", "1"), + resource.TestCheckResourceAttrPair(dataName2, "ids.0", serverName, "id"), + ), + }, + }, + }) +} + +func testAccDataSourceServersVpcConfig(testServerName, testServerName2 string) string { + return fmt.Sprintf(` +resource "ncloud_login_key" "loginkey" { + key_name = "%[1]s-key" +} + +resource "ncloud_vpc" "test" { + name = "%[1]s" + ipv4_cidr_block = "10.5.0.0/16" +} + +resource "ncloud_subnet" "test" { + vpc_no = ncloud_vpc.test.vpc_no + name = "%[1]s" + subnet = "10.5.0.0/24" + zone = "KR-2" + network_acl_no = ncloud_vpc.test.default_network_acl_no + subnet_type = "PUBLIC" + usage_type = "GEN" +} + +resource "ncloud_server" "test" { + subnet_no = ncloud_subnet.test.id + name = "%[1]s" + server_image_product_code = "SW.VSVR.OS.LNX64.CNTOS.0703.B050" + server_product_code = "SVR.VSVR.STAND.C002.M008.NET.HDD.B050.G002" + login_key_name = ncloud_login_key.loginkey.key_name +} + +resource "ncloud_server" "test2" { + subnet_no = ncloud_subnet.test.id + name = "%[2]s" + server_image_product_code = "SW.VSVR.OS.LNX64.CNTOS.0703.B050" + server_product_code = "SVR.VSVR.STAND.C002.M008.NET.HDD.B050.G002" + login_key_name = ncloud_login_key.loginkey.key_name +} + +data "ncloud_servers" "by_id" { + ids = [ncloud_server.test.id, ncloud_server.test2.id] +} + +data "ncloud_servers" "by_filter" { + filter { + name = "instance_no" + values = [ncloud_server.test.id] + } +} +`, testServerName, testServerName2) +} + +func testAccDataSourceServersClassicConfig(testServerName, testServerName2 string) string { + return fmt.Sprintf(` +resource "ncloud_login_key" "loginkey" { + key_name = "%[1]s-key" +} + +resource "ncloud_server" "test" { + name = "%[1]s" + server_image_product_code = "SPSW0LINUX000139" + server_product_code = "SPSVRSSD00000003" + login_key_name = "${ncloud_login_key.loginkey.key_name}" +} + +resource "ncloud_server" "test2" { + name = "%[2]s" + server_image_product_code = "SPSW0LINUX000139" + server_product_code = "SPSVRSSD00000003" + login_key_name = "${ncloud_login_key.loginkey.key_name}" +} + +data "ncloud_servers" "by_id" { + ids = [ncloud_server.test.id, ncloud_server.test2.id] +} + +data "ncloud_servers" "by_filter" { + filter { + name = "instance_no" + values = [ncloud_server.test.id] + } +} +`, testServerName, testServerName2) +}