From 7f94160f3fe90ee0f8954444f8abfa8cc86f0ff5 Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 26 Feb 2020 13:19:48 -0600 Subject: [PATCH 01/12] chore: added public_ip_id as a required attribute for single datasource publicIP --- outscale/data_source_outscale_public_ip.go | 20 +++++++----- .../data_source_outscale_public_ip_test.go | 31 +++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/outscale/data_source_outscale_public_ip.go b/outscale/data_source_outscale_public_ip.go index aa13de4d8..3d10b29c1 100644 --- a/outscale/data_source_outscale_public_ip.go +++ b/outscale/data_source_outscale_public_ip.go @@ -3,12 +3,13 @@ package outscale import ( "context" "fmt" - "github.com/antihax/optional" - oscgo "github.com/marinsalinas/osc-sdk-go" "log" "strings" "time" + "github.com/antihax/optional" + oscgo "github.com/marinsalinas/osc-sdk-go" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) @@ -26,7 +27,7 @@ func getOAPIPublicIPDataSourceSchema() map[string]*schema.Schema { "filter": dataSourceFiltersSchema(), "public_ip_id": { Type: schema.TypeString, - Optional: true, + Required: true, }, "public_ip": { Type: schema.TypeString, @@ -65,16 +66,13 @@ func dataSourceOutscaleOAPIPublicIPRead(d *schema.ResourceData, meta interface{} req := oscgo.ReadPublicIpsRequest{ Filters: &oscgo.FiltersPublicIp{}, } + req.Filters.SetPublicIpIds([]string{d.Get("public_ip_id").(string)}) filters, filtersOk := d.GetOk("filter") - if filtersOk { req.Filters = buildOutscaleOAPIDataSourcePublicIpsFilters(filters.(*schema.Set)) } - if id := d.Get("public_ip_id"); id != "" { - req.Filters.SetPublicIpIds([]string{id.(string)}) - } if id := d.Get("public_ip"); id != "" { req.Filters.SetPublicIps([]string{id.(string)}) } @@ -168,7 +166,7 @@ func buildOutscaleOAPIDataSourcePublicIpsFilters(set *schema.Set) *oscgo.Filters switch name := m["name"].(string); name { case "public_ip_ids": filters.SetPublicIpIds(filterValues) - case "link_ids": + case "link_public_ip_id": filters.SetLinkPublicIpIds(filterValues) case "placements": filters.SetPlacements(filterValues) @@ -182,6 +180,12 @@ func buildOutscaleOAPIDataSourcePublicIpsFilters(set *schema.Set) *oscgo.Filters filters.SetPrivateIps(filterValues) case "public_ips": filters.SetPublicIps(filterValues) + case "tags": + filters.SetTags(filterValues) + case "tag_keys": + filters.SetTagKeys(filterValues) + case "tag_values": + filters.SetTagValues(filterValues) default: log.Printf("[Debug] Unknown Filter Name: %s.", name) } diff --git a/outscale/data_source_outscale_public_ip_test.go b/outscale/data_source_outscale_public_ip_test.go index ed36b9a08..3140b022f 100644 --- a/outscale/data_source_outscale_public_ip_test.go +++ b/outscale/data_source_outscale_public_ip_test.go @@ -60,6 +60,19 @@ func testAccDataSourceOutscaleOAPIPublicIPCheck(name string) resource.TestCheckF } } +func TestAccDataSourceOutscaleOAPIPublicIP_withTags(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceOutscaleOAPIPublicIPConfigWithTags, + }, + }, + }) +} + const testAccDataSourceOutscaleOAPIPublicIPConfig = ` resource "outscale_public_ip" "test" {} @@ -74,3 +87,21 @@ const testAccDataSourceOutscaleOAPIPublicIPConfig = ` } } ` + +const testAccDataSourceOutscaleOAPIPublicIPConfigWithTags = ` + resource "outscale_public_ip" "outscale_public_ip" { + tags { + key = "name" + value = "public_ip-data" + } + } + + data "outscale_public_ip" "outscale_public_ip" { + public_ip_id = outscale_public_ip.outscale_public_ip.public_ip_id + + filter { + name = "tags" + values = ["name=public_ip-data"] + } + } +` From 69fd9ddacb2446afe50e91ef510867ca38d0e383 Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 26 Feb 2020 13:20:29 -0600 Subject: [PATCH 02/12] chore: refactored code --- outscale/data_source_outscale_public_ips.go | 13 +++--- .../data_source_outscale_public_ips_test.go | 40 ++++++++++++++++++- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/outscale/data_source_outscale_public_ips.go b/outscale/data_source_outscale_public_ips.go index 466faf369..0d05f80d5 100644 --- a/outscale/data_source_outscale_public_ips.go +++ b/outscale/data_source_outscale_public_ips.go @@ -3,18 +3,19 @@ package outscale import ( "context" "fmt" - "github.com/antihax/optional" - oscgo "github.com/marinsalinas/osc-sdk-go" "strings" "time" + "github.com/antihax/optional" + oscgo "github.com/marinsalinas/osc-sdk-go" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) func dataSourceOutscaleOAPIPublicIPS() *schema.Resource { return &schema.Resource{ - Read: oapiDataSourceOutscalePublicIPSRead, + Read: dataSourceOutscalePublicIPSRead, Schema: oapiGetPublicIPSDataSourceSchema(), } } @@ -66,7 +67,7 @@ func oapiGetPublicIPSDataSourceSchema() map[string]*schema.Schema { } } -func oapiDataSourceOutscalePublicIPSRead(d *schema.ResourceData, meta interface{}) error { +func dataSourceOutscalePublicIPSRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*OutscaleClient).OSCAPI req := oscgo.ReadPublicIpsRequest{} @@ -120,7 +121,5 @@ func oapiDataSourceOutscalePublicIPSRead(d *schema.ResourceData, meta interface{ d.Set("request_id", resp.ResponseContext.GetRequestId()) - err = d.Set("public_ips", address) - - return err + return d.Set("public_ips", address) } diff --git a/outscale/data_source_outscale_public_ips_test.go b/outscale/data_source_outscale_public_ips_test.go index 34c40d787..27d871d66 100644 --- a/outscale/data_source_outscale_public_ips_test.go +++ b/outscale/data_source_outscale_public_ips_test.go @@ -27,6 +27,19 @@ func TestAccDataSourceOutscaleOAPIPublicIPS(t *testing.T) { }) } +func TestAccDataSourceOutscaleOAPIPublicIPS_withTags(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceOutscaleOAPIPublicIPSConfigWithTags, + }, + }, + }) +} + const testAccDataSourceOutscaleOAPIPublicIPSConfig = ` resource "outscale_public_ip" "test" {} resource "outscale_public_ip" "test1" {} @@ -36,6 +49,31 @@ const testAccDataSourceOutscaleOAPIPublicIPSConfig = ` filter { name = "public_ip" values = ["${outscale_public_ip.test.public_ip}", "${outscale_public_ip.test1.public_ip}", "${outscale_public_ip.test2.public_ip}"] - } + } + } +` + +const testAccDataSourceOutscaleOAPIPublicIPSConfigWithTags = ` + resource "outscale_public_ip" "outscale_public_ip" { + tags { + key = "name" + value = "public_ip-data" + } + } + + resource "outscale_public_ip" "outscale_public_ip2" { + tags { + key = "name" + value = "public_ip-data" + } + } + + data "outscale_public_ips" "outscale_public_ips" { + filter { + name = "tags" + values = ["name=public_ip-data"] + } + + depends_on = [outscale_public_ip.outscale_public_ip, outscale_public_ip.outscale_public_ip2] } ` From a1392bca0e083c6d4b888212523602cfbcf5070b Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 19 Feb 2020 11:58:28 -0600 Subject: [PATCH 03/12] chore: added log.* insto the .gitignore file --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4b921bc5f..f902286dd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,6 @@ log.txt terraform-provider-outscale *.log *.out - +log.* .DS_Store *~ From ff55a68e59721b5edee4e46893272383cb924d89 Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 19 Feb 2020 11:59:14 -0600 Subject: [PATCH 04/12] chore: added importer function in vm resource --- outscale/resource_outscale_vm.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/outscale/resource_outscale_vm.go b/outscale/resource_outscale_vm.go index 0df564336..2f9eba593 100644 --- a/outscale/resource_outscale_vm.go +++ b/outscale/resource_outscale_vm.go @@ -25,7 +25,9 @@ func resourceOutscaleOApiVM() *schema.Resource { Read: resourceOAPIVMRead, Update: resourceOAPIVMUpdate, Delete: resourceOAPIVMDelete, - + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(10 * time.Minute), Update: schema.DefaultTimeout(10 * time.Minute), From 0a0ae396c1bc468818b1552a399fe29dc1cab0c1 Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 19 Feb 2020 11:59:49 -0600 Subject: [PATCH 05/12] chore: added test for the import function --- outscale/resource_outscale_vm_test.go | 94 ++++++++++++++++++--------- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/outscale/resource_outscale_vm_test.go b/outscale/resource_outscale_vm_test.go index 5ac7f87b6..57af9e835 100644 --- a/outscale/resource_outscale_vm_test.go +++ b/outscale/resource_outscale_vm_test.go @@ -42,6 +42,40 @@ func TestAccOutscaleOAPIVM_Basic(t *testing.T) { }) } +func TestAccOutscaleOAPIVM_importBasic(t *testing.T) { + omi := getOMIByRegion("eu-west-2", "centos").OMI + region := os.Getenv("OUTSCALE_REGION") + resourceName := "outscale_vm.basic" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { skipIfNoOAPI(t); testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckOutscaleOAPIVMDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckOutscaleOAPIVMConfigBasic(omi, "c4.large", region), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccCheckOutscaleVMImportStateIDFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"private_ips", "request_id"}, + }, + }, + }) +} + +func testAccCheckOutscaleVMImportStateIDFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + return rs.Primary.ID, nil + } +} + func TestAccOutscaleOAPIVM_BasicWithNicAttached(t *testing.T) { var server oscgo.Vm omi := os.Getenv("OUTSCALE_IMAGEID") @@ -563,45 +597,45 @@ func testAccCheckOutscaleOAPIVMConfigBasicWithNics(omi, vmType string) string { return fmt.Sprintf(`resource "outscale_net" "outscale_net" { ip_range = "10.0.0.0/16" } - + resource "outscale_subnet" "outscale_subnet" { net_id = "${outscale_net.outscale_net.net_id}" ip_range = "10.0.0.0/24" subregion_name = "eu-west-2a" } - + resource "outscale_nic" "outscale_nic" { subnet_id = "${outscale_subnet.outscale_subnet.subnet_id}" } - + resource "outscale_security_group" "outscale_security_group" { description = "test vm with nic" security_group_name = "private-sg" net_id = "${outscale_net.outscale_net.net_id}" } - + resource "outscale_vm" "basic" { image_id = "%s" vm_type = "%s" keypair_name = "terraform-basic" - + # subnet_id ="${outscale_subnet.outscale_subnet.subnet_id}" nics { # delete_on_vm_deletion = false # description = "myDescription" device_number = 0 - + # nic_id = "${outscale_nic.outscale_nic.nic_id}" # secondary_private_ip_count = 1 subnet_id = "${outscale_subnet.outscale_subnet.subnet_id}" - + security_group_ids = ["${outscale_security_group.outscale_security_group.security_group_id}"] - + private_ips { private_ip = "10.0.0.123" is_primary = true } - + private_ips { private_ip = "10.0.0.124" is_primary = false @@ -649,19 +683,19 @@ func testAccCheckOutscaleOAPIVMConfigWithSubnet(omi, vmType string, region strin value = "testacc-vm-rs" } } - + resource "outscale_subnet" "outscale_subnet" { subregion_name = "%[3]sa" ip_range = "10.0.0.0/16" net_id = "${outscale_net.outscale_net.net_id}" } - + resource "outscale_security_group" "outscale_security_group" { description = "test group" security_group_name = "sg1-test-group_test-net" net_id = "${outscale_net.outscale_net.net_id}" } - + resource "outscale_vm" "basic" { image_id = "%[1]s" vm_type = "%[2]s" @@ -670,7 +704,7 @@ func testAccCheckOutscaleOAPIVMConfigWithSubnet(omi, vmType string, region strin subnet_id = "${outscale_subnet.outscale_subnet.subnet_id}" placement_subregion_name = "%sa" placement_tenancy = "default" - } + } `, omi, vmType, region) } @@ -680,16 +714,16 @@ func testAccCheckOutscaleOAPIVMConfigWithBlockDeviceMappings(omi, vmType, region subregion_name = "eu-west-2a" size = 1 } - + resource "outscale_snapshot" "snapshot" { volume_id = "${outscale_volume.external1.id}" } - + resource "outscale_vm" "basic" { image_id = "%[1]s" vm_type = "%[2]s" keypair_name = "terraform-basic" - + block_device_mappings { device_name = "/dev/sdb" no_device = "/dev/xvdb" @@ -700,7 +734,7 @@ func testAccCheckOutscaleOAPIVMConfigWithBlockDeviceMappings(omi, vmType, region delete_on_vm_deletion = true } } - + block_device_mappings { device_name = "/dev/sdc" bsu = { @@ -711,7 +745,7 @@ func testAccCheckOutscaleOAPIVMConfigWithBlockDeviceMappings(omi, vmType, region delete_on_vm_deletion = true } } - + block_device_mappings { device_name = "/dev/sdc" bsu = { @@ -729,18 +763,18 @@ func testAccCheckOutscaleOAPIVMConfigWithNet(omi, vmType, region string) string return fmt.Sprintf(` resource "outscale_net" "outscale_net" { ip_range = "10.0.0.0/16" - - tags { - key = "Name" - value = "testacc-vm-rs" + + tags { + key = "name" + value = "Terraform_net" } } resource "outscale_subnet" "outscale_subnet" { net_id = "${outscale_net.outscale_net.net_id}" ip_range = "10.0.0.0/24" - subregion_name = "%[3]sb" - - tags { + subregion_name = "%[3]sb" + + tags { key = "name" value = "Terraform_subnet" } @@ -751,13 +785,13 @@ func testAccCheckOutscaleOAPIVMConfigWithNet(omi, vmType, region string) string security_group_name = "terraform-sg" net_id = "${outscale_net.outscale_net.net_id}" } - + resource "outscale_internet_service" "outscale_internet_service" {} resource "outscale_route_table" "outscale_route_table" { net_id = "${outscale_net.outscale_net.net_id}" - - tags { + + tags { key = "name" value = "Terraform_RT" } @@ -769,7 +803,7 @@ func testAccCheckOutscaleOAPIVMConfigWithNet(omi, vmType, region string) string } resource "outscale_internet_service_link" "outscale_internet_service_link" { - internet_service_id = "${outscale_internet_service.outscale_internet_service.internet_service_id}" + internet_service_id = "${outscale_internet_service.outscale_internet_service.internet_service_id}" net_id = "${outscale_net.outscale_net.net_id}" } @@ -777,7 +811,7 @@ func testAccCheckOutscaleOAPIVMConfigWithNet(omi, vmType, region string) string gateway_id = "${outscale_internet_service.outscale_internet_service.internet_service_id}" destination_ip_range = "0.0.0.0/0" route_table_id = "${outscale_route_table.outscale_route_table.route_table_id}" - } + } resource "outscale_vm" "outscale_vmnet" { image_id = "%[1]s" vm_type = "%[2]s" From d6989223b4658ec2f2e3ab7f81fe34e3925fa5f2 Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 19 Feb 2020 15:03:08 -0600 Subject: [PATCH 06/12] refactor: refactored code to implement import --- .../resource_outscale_route_table_link.go | 113 ++++++++++++------ 1 file changed, 79 insertions(+), 34 deletions(-) diff --git a/outscale/resource_outscale_route_table_link.go b/outscale/resource_outscale_route_table_link.go index eccda7b47..1d1d3af0d 100644 --- a/outscale/resource_outscale_route_table_link.go +++ b/outscale/resource_outscale_route_table_link.go @@ -2,6 +2,7 @@ package outscale import ( "context" + "errors" "fmt" "log" "strings" @@ -14,28 +15,29 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) +const ( + errorLinkRouteTableSetting = "error setting `%s` for Link Route Table (%s): %s" +) + func resourceOutscaleOAPILinkRouteTable() *schema.Resource { return &schema.Resource{ Create: resourceOutscaleOAPILinkRouteTableCreate, Read: resourceOutscaleOAPILinkRouteTableRead, Delete: resourceOutscaleOAPILinkRouteTableDelete, Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceOutscaleOAPILinkRouteTableImportState, }, - Schema: map[string]*schema.Schema{ "subnet_id": &schema.Schema{ Type: schema.TypeString, Required: true, ForceNew: true, }, - "route_table_id": &schema.Schema{ Type: schema.TypeString, Required: true, ForceNew: true, }, - "link_route_table_id": &schema.Schema{ Type: schema.TypeString, Computed: true, @@ -87,47 +89,27 @@ func resourceOutscaleOAPILinkRouteTableCreate(d *schema.ResourceData, meta inter } d.SetId(resp.GetLinkRouteTableId()) - if err := d.Set("link_route_table_id", d.Id()); err != nil { - return err - } - if err := d.Set("request_id", resp.ResponseContext.GetRequestId()); err != nil { - return err - } - log.Printf("[INFO] LinkRouteTable ID: %s", d.Id()) return nil } func resourceOutscaleOAPILinkRouteTableRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*OutscaleClient).OSCAPI - - rtRaw, _, err := resourceOutscaleOAPIRouteTableStateRefreshFunc( - conn, d.Get("route_table_id").(string), d.Get("link_route_table_id").(string))() + routeTable, requestID, err := readOutscaleLinkRouteTable(meta.(*OutscaleClient), d.Get("route_table_id").(string), d.Id()) if err != nil { return err } - if rtRaw == nil { - return nil + if routeTable == nil { + d.SetId("") } - rt := rtRaw.(oscgo.RouteTable) - log.Printf("[DEBUG] LinkRouteTables: %v and %v", rt.LinkRouteTables, d.Get("link_route_table_id")) - found := false - for _, a := range rt.GetLinkRouteTables() { - if a.GetLinkRouteTableId() == d.Id() { - found = true - if err := d.Set("subnet_id", a.GetSubnetId()); err != nil { - return err - } - if err := d.Set("main", a.GetMain()); err != nil { - return err - } - break - } + if err := d.Set("link_route_table_id", routeTable.GetLinkRouteTableId()); err != nil { + return fmt.Errorf(errorLinkRouteTableSetting, "link_route_table_id", routeTable.GetLinkRouteTableId(), err) } - - if !found { - d.SetId("") + if err := d.Set("main", routeTable.GetMain()); err != nil { + return fmt.Errorf(errorLinkRouteTableSetting, "main", routeTable.GetLinkRouteTableId(), err) + } + if err := d.Set("request_id", requestID); err != nil { + return fmt.Errorf(errorLinkRouteTableSetting, "request_id", routeTable.GetLinkRouteTableId(), err) } return nil @@ -161,3 +143,66 @@ func resourceOutscaleOAPILinkRouteTableDelete(d *schema.ResourceData, meta inter return nil } + +func resourceOutscaleOAPILinkRouteTableImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parts := strings.SplitN(d.Id(), "_", 2) + if len(parts) != 2 { + return nil, errors.New("import format error: to import a Link Route Table, use the format {route_table_id}-{link_route_table_id}") + } + + routeTableID := parts[0] + linkRouteTableID := parts[1] + + routeTable, _, err := readOutscaleLinkRouteTable(meta.(*OutscaleClient), routeTableID, linkRouteTableID) + if err != nil { + return nil, fmt.Errorf("couldn't import Link Route Table(%s), error: %s", linkRouteTableID, err) + } + + if err := d.Set("route_table_id", routeTable.GetRouteTableId()); err != nil { + return nil, fmt.Errorf(errorLinkRouteTableSetting, "route_table_id", routeTable.GetLinkRouteTableId(), err) + } + if err := d.Set("subnet_id", routeTable.GetSubnetId()); err != nil { + return nil, fmt.Errorf(errorLinkRouteTableSetting, "subnet_id", routeTable.GetLinkRouteTableId(), err) + } + + d.SetId(linkRouteTableID) + + return []*schema.ResourceData{d}, nil +} + +func readOutscaleLinkRouteTable(meta *OutscaleClient, routeTableID, linkRouteTableID string) (*oscgo.LinkRouteTable, string, error) { + conn := meta.OSCAPI + + var rt oscgo.ReadRouteTablesResponse + var err error + + err = resource.Retry(15*time.Minute, func() *resource.RetryError { + rt, _, err = conn.RouteTableApi.ReadRouteTables(context.Background(), + &oscgo.ReadRouteTablesOpts{ + ReadRouteTablesRequest: optional.NewInterface(oscgo.ReadRouteTablesRequest{ + Filters: &oscgo.FiltersRouteTable{RouteTableIds: &[]string{routeTableID}}, + }), + }) + if err != nil { + if strings.Contains(fmt.Sprint(err), "RequestLimitExceeded") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + if err != nil { + return nil, rt.ResponseContext.GetRequestId(), err + } + + return getLinkRouteTable(linkRouteTableID, rt.GetRouteTables()[0].GetLinkRouteTables()), rt.ResponseContext.GetRequestId(), nil +} + +func getLinkRouteTable(id string, routeTables []oscgo.LinkRouteTable) (routeTable *oscgo.LinkRouteTable) { + for _, rt := range routeTables { + if rt.GetLinkRouteTableId() == id { + routeTable = &rt + } + } + return +} From 23283c717da52add5422930037d784ae99a9ac3f Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Wed, 19 Feb 2020 15:03:27 -0600 Subject: [PATCH 07/12] chore: added test case to import function chore: changed error comment in import function --- .../resource_outscale_route_table_link.go | 2 +- ...resource_outscale_route_table_link_test.go | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/outscale/resource_outscale_route_table_link.go b/outscale/resource_outscale_route_table_link.go index 1d1d3af0d..bf17a3c61 100644 --- a/outscale/resource_outscale_route_table_link.go +++ b/outscale/resource_outscale_route_table_link.go @@ -147,7 +147,7 @@ func resourceOutscaleOAPILinkRouteTableDelete(d *schema.ResourceData, meta inter func resourceOutscaleOAPILinkRouteTableImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { parts := strings.SplitN(d.Id(), "_", 2) if len(parts) != 2 { - return nil, errors.New("import format error: to import a Link Route Table, use the format {route_table_id}-{link_route_table_id}") + return nil, errors.New("import format error: to import a Link Route Table, use the format {route_table_id}_{link_route_table_id}") } routeTableID := parts[0] diff --git a/outscale/resource_outscale_route_table_link_test.go b/outscale/resource_outscale_route_table_link_test.go index deea8132c..4104eb4ad 100644 --- a/outscale/resource_outscale_route_table_link_test.go +++ b/outscale/resource_outscale_route_table_link_test.go @@ -33,6 +33,38 @@ func TestAccOutscaleOAPILinkRouteTable_basic(t *testing.T) { }) } +func TestAccResourceOAPILinkRouteTable_importBasic(t *testing.T) { + resourceName := "outscale_route_table_link.foo" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckOAPILinkRouteTableDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOAPILinkRouteTableConfig, + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccCheckOAPILinkRouteTableImportStateIDFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"request_id"}, + }, + }, + }) +} + +func testAccCheckOAPILinkRouteTableImportStateIDFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + return fmt.Sprintf("%s_%s", rs.Primary.Attributes["route_table_id"], rs.Primary.ID), nil + } +} + func testAccCheckOAPILinkRouteTableDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*OutscaleClient).OSCAPI From 95879b4a2e33073161e6b91c012c46d74a774e21 Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Thu, 20 Feb 2020 16:03:38 -0600 Subject: [PATCH 08/12] refactor: refactored code adding missing attributes --- outscale/resource_outscale_volume_link.go | 60 +++++++++++++---------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/outscale/resource_outscale_volume_link.go b/outscale/resource_outscale_volume_link.go index 2cb0aaf7c..499fd24c0 100644 --- a/outscale/resource_outscale_volume_link.go +++ b/outscale/resource_outscale_volume_link.go @@ -1,7 +1,6 @@ package outscale import ( - "bytes" "context" "fmt" "log" @@ -10,9 +9,10 @@ import ( "github.com/antihax/optional" oscgo "github.com/marinsalinas/osc-sdk-go" + "github.com/openlyinc/pointy" + "github.com/spf13/cast" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) @@ -45,18 +45,16 @@ func getOAPIVolumeLinkSchema() map[string]*schema.Schema { }, "vm_id": { Type: schema.TypeString, - Optional: true, - ForceNew: true, - Computed: true, - }, - "force_unlink": { - Type: schema.TypeBool, - Optional: true, + Required: true, ForceNew: true, - Computed: true, }, "volume_id": { Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "force_unlink": { + Type: schema.TypeBool, Optional: true, ForceNew: true, Computed: true, @@ -173,7 +171,7 @@ func resourceOAPIVolumeLinkCreate(d *schema.ResourceData, meta interface{}) erro vID, iID, err) } - d.SetId(volumeOAPIAttachmentID(name, vID, iID)) + d.SetId(vID) return resourceOAPIVolumeLinkRead(d, meta) } @@ -241,7 +239,7 @@ func resourceOAPIVolumeLinkRead(d *schema.ResourceData, meta interface{}) error request := oscgo.ReadVolumesRequest{ Filters: &oscgo.FiltersVolume{ - VolumeIds: &[]string{d.Get("volume_id").(string)}, + VolumeIds: &[]string{d.Id()}, }, } @@ -268,8 +266,28 @@ func resourceOAPIVolumeLinkRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error reading Outscale volume %s for instance: %s: %#v", d.Get("volume_id").(string), d.Get("vm_id").(string), err) } + var linkedVolume oscgo.LinkedVolume + for _, vol := range vols.GetVolumes()[0].GetLinkedVolumes() { + linkedVolume = vol + } + + if err := d.Set("device_name", linkedVolume.GetDeviceName()); err != nil { + return fmt.Errorf("error sertting %s in Volume Link(%s): %s", `device_name`, linkedVolume.GetVolumeId(), err) + } + if err := d.Set("vm_id", linkedVolume.GetVmId()); err != nil { + return fmt.Errorf("error sertting %s in Volume Link(%s): %s", `vm_id`, linkedVolume.GetVolumeId(), err) + } + if err := d.Set("volume_id", linkedVolume.GetVolumeId()); err != nil { + return fmt.Errorf("error sertting %s in Volume Link(%s): %s", `volume_id`, linkedVolume.GetVolumeId(), err) + } + if err := d.Set("delete_on_vm_termination", linkedVolume.GetDeleteOnVmDeletion()); err != nil { + return fmt.Errorf("error sertting %s in Volume Link(%s): %s", `delete_on_vm_termination`, linkedVolume.GetVolumeId(), err) + } + if err := d.Set("state", linkedVolume.GetState()); err != nil { + return fmt.Errorf("error sertting %s in Volume Link(%s): %s", `state`, linkedVolume.GetVolumeId(), err) + } if err := d.Set("request_id", vols.ResponseContext.GetRequestId()); err != nil { - return err + return fmt.Errorf("error sertting %s in Volume Link(%s): %s", `request_id`, linkedVolume.GetVolumeId(), err) } if len(vols.GetVolumes()) == 0 || vols.GetVolumes()[0].GetState() == "available" || isElegibleToLink(vols.GetVolumes(), d.Get("vm_id").(string)) { @@ -278,7 +296,6 @@ func resourceOAPIVolumeLinkRead(d *schema.ResourceData, meta interface{}) error } return nil - } func resourceOAPIVolumeLinkDelete(d *schema.ResourceData, meta interface{}) error { @@ -290,14 +307,14 @@ func resourceOAPIVolumeLinkDelete(d *schema.ResourceData, meta interface{}) erro return nil } - vID := d.Get("volume_id").(string) + vID := d.Id() iID := d.Get("vm_id").(string) opts := oscgo.UnlinkVolumeRequest{ //VmId: iID, - //ForceUnlink: d.Get("force_unlink").(bool), //DeviceName: d.Get("device_name").(string), //Removed due oAPI Bug. - VolumeId: vID, + ForceUnlink: pointy.Bool(cast.ToBool(d.Get("force_unlink"))), + VolumeId: vID, } force, forceOk := d.GetOk("force_unlink") @@ -342,12 +359,3 @@ func resourceOAPIVolumeLinkDelete(d *schema.ResourceData, meta interface{}) erro d.SetId("") return nil } - -func volumeOAPIAttachmentID(name, volumeID, instanceID string) string { - var buf bytes.Buffer - buf.WriteString(fmt.Sprintf("%s-", name)) - buf.WriteString(fmt.Sprintf("%s-", instanceID)) - buf.WriteString(fmt.Sprintf("%s-", volumeID)) - - return fmt.Sprintf("vai-%d", hashcode.String(buf.String())) -} From d51d3b305a92598fb55176bc24e305d6a6d2222a Mon Sep 17 00:00:00 2001 From: PacoDw <__pm@outlook.com> Date: Thu, 20 Feb 2020 16:03:47 -0600 Subject: [PATCH 09/12] chore: added test case for import function --- .../resource_outscale_volume_link_test.go | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/outscale/resource_outscale_volume_link_test.go b/outscale/resource_outscale_volume_link_test.go index 9c85a3d75..a8cdaf1a0 100644 --- a/outscale/resource_outscale_volume_link_test.go +++ b/outscale/resource_outscale_volume_link_test.go @@ -40,6 +40,41 @@ func TestAccOutscaleOAPIVolumeAttachment_basic(t *testing.T) { }) } +func TestAccOutscaleOAPIVolumeAttachment_importBasic(t *testing.T) { + omi := os.Getenv("OUTSCALE_IMAGEID") + region := os.Getenv("OUTSCALE_REGION") + + resourceName := "outscale_volumes_link.ebs_att" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckOAPIVolumeAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOAPIVolumeAttachmentConfig(omi, "c4.large", region), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccCheckOAPIVolumeAttachmentImportStateIDFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"request_id"}, + }, + }, + }) +} + +func testAccCheckOAPIVolumeAttachmentImportStateIDFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + return rs.Primary.ID, nil + } +} + func testAccCheckOAPIVolumeAttachmentDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "outscale_volume_link" { From ff7737927814d37eacf69cd1ce5543f43efe2501 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 28 Feb 2020 10:46:03 -0600 Subject: [PATCH 10/12] refactor: resource/public_ip - change public_ip_id to optional instead required --- outscale/data_source_outscale_public_ip.go | 15 +++++++++------ outscale/data_source_outscale_public_ip_test.go | 9 ++++++--- outscale/data_source_outscale_public_ips_test.go | 6 ++---- outscale/resource_outscale_vm_test.go | 4 ++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/outscale/data_source_outscale_public_ip.go b/outscale/data_source_outscale_public_ip.go index 152baff08..5ad58846d 100644 --- a/outscale/data_source_outscale_public_ip.go +++ b/outscale/data_source_outscale_public_ip.go @@ -27,7 +27,7 @@ func getOAPIPublicIPDataSourceSchema() map[string]*schema.Schema { "filter": dataSourceFiltersSchema(), "public_ip_id": { Type: schema.TypeString, - Required: true, + Optional: true, }, "public_ip": { Type: schema.TypeString, @@ -66,17 +66,20 @@ func dataSourceOutscaleOAPIPublicIPRead(d *schema.ResourceData, meta interface{} req := oscgo.ReadPublicIpsRequest{ Filters: &oscgo.FiltersPublicIp{}, } - req.Filters.SetPublicIpIds([]string{d.Get("public_ip_id").(string)}) - filters, filtersOk := d.GetOk("filter") - if filtersOk { - req.Filters = buildOutscaleOAPIDataSourcePublicIpsFilters(filters.(*schema.Set)) + if p, ok := d.GetOk("public_ip_id"); ok { + req.Filters.SetPublicIpIds([]string{p.(string)}) } - if id := d.Get("public_ip"); id != "" { + if id, ok := d.GetOk("public_ip"); ok { req.Filters.SetPublicIps([]string{id.(string)}) } + filters, filtersOk := d.GetOk("filter") + if filtersOk { + req.Filters = buildOutscaleOAPIDataSourcePublicIpsFilters(filters.(*schema.Set)) + } + var response oscgo.ReadPublicIpsResponse err := resource.Retry(60*time.Second, func() *resource.RetryError { var err error diff --git a/outscale/data_source_outscale_public_ip_test.go b/outscale/data_source_outscale_public_ip_test.go index 3140b022f..159763b0f 100644 --- a/outscale/data_source_outscale_public_ip_test.go +++ b/outscale/data_source_outscale_public_ip_test.go @@ -97,11 +97,14 @@ const testAccDataSourceOutscaleOAPIPublicIPConfigWithTags = ` } data "outscale_public_ip" "outscale_public_ip" { - public_ip_id = outscale_public_ip.outscale_public_ip.public_ip_id - filter { name = "tags" - values = ["name=public_ip-data"] + values = ["name=${outscale_public_ip.outscale_public_ip.tags[0].value}"] + } + + filter { + name = "public_ip_ids" + values = [outscale_public_ip.outscale_public_ip.public_ip_id] } } ` diff --git a/outscale/data_source_outscale_public_ips_test.go b/outscale/data_source_outscale_public_ips_test.go index 27d871d66..7413be25a 100644 --- a/outscale/data_source_outscale_public_ips_test.go +++ b/outscale/data_source_outscale_public_ips_test.go @@ -64,16 +64,14 @@ const testAccDataSourceOutscaleOAPIPublicIPSConfigWithTags = ` resource "outscale_public_ip" "outscale_public_ip2" { tags { key = "name" - value = "public_ip-data" + value = outscale_public_ip.outscale_public_ip.tags[0].value } } data "outscale_public_ips" "outscale_public_ips" { filter { name = "tags" - values = ["name=public_ip-data"] + values = ["name=${outscale_public_ip.outscale_public_ip.tags[0].value}"] } - - depends_on = [outscale_public_ip.outscale_public_ip, outscale_public_ip.outscale_public_ip2] } ` diff --git a/outscale/resource_outscale_vm_test.go b/outscale/resource_outscale_vm_test.go index 57af9e835..009aa5cf7 100644 --- a/outscale/resource_outscale_vm_test.go +++ b/outscale/resource_outscale_vm_test.go @@ -43,12 +43,12 @@ func TestAccOutscaleOAPIVM_Basic(t *testing.T) { } func TestAccOutscaleOAPIVM_importBasic(t *testing.T) { - omi := getOMIByRegion("eu-west-2", "centos").OMI + omi := os.Getenv("OUTSCALE_IMAGEID") region := os.Getenv("OUTSCALE_REGION") resourceName := "outscale_vm.basic" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { skipIfNoOAPI(t); testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckOutscaleOAPIVMDestroy, Steps: []resource.TestStep{ From 95107983d53aa8e4bc1c0a661d9522c425c4ccd6 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 28 Feb 2020 11:57:55 -0600 Subject: [PATCH 11/12] chore: data_source/public_ip - change error message when get multiple public ips --- outscale/data_source_outscale_public_ip.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/outscale/data_source_outscale_public_ip.go b/outscale/data_source_outscale_public_ip.go index 5ad58846d..39580314a 100644 --- a/outscale/data_source_outscale_public_ip.go +++ b/outscale/data_source_outscale_public_ip.go @@ -104,11 +104,11 @@ func dataSourceOutscaleOAPIPublicIPRead(d *schema.ResourceData, meta interface{} // Verify Outscale returned our EIP if len(response.GetPublicIps()) == 0 { - return fmt.Errorf("Unable to find EIP: %#v", response.GetPublicIps()) + return fmt.Errorf("Unable to find Public IP: %#v", req) } if len(response.GetPublicIps()) > 1 { - return fmt.Errorf("multiple External IPs matched; use additional constraints to reduce matches to a single External IP") + return fmt.Errorf("multiple Public IPs matched; you can either use additional constraints to reduce matches to a single Public IP or use public_ips data source instead.") } address := response.GetPublicIps()[0] From 743b115cae6a1067b7f3f7555bbd8ad5711cece7 Mon Sep 17 00:00:00 2001 From: Marin Salinas Date: Fri, 28 Feb 2020 16:15:05 -0600 Subject: [PATCH 12/12] chore: change readme links to RC8.1 --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d20393846..617c24f35 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,9 @@ Installing The Provider on Linux Download the binary and install it in ~/.terraform.d/plugins/linux_amd64/. ```sh -$ wget https://github.com/outscale-dev/terraform-provider-outscale/releases/download/release-0.1.0RC8/terraform-provider-outscale_linux_amd64_v0.1.0-rc8.zip -$ unzip terraform-provider-outscale_linux_amd64_v0.1.0-rc8.zip -$ mv terraform-provider-outscale_v0.1.0-rc8 ~/.terraform.d/plugins/linux_amd64/. +$ wget https://github.com/outscale-dev/terraform-provider-outscale/releases/download/release-0.1.0RC8.1/terraform-provider-outscale_linux_amd64_v0.1.0-rc8.1.zip +$ unzip terraform-provider-outscale_linux_amd64_v0.1.0-rc8.1.zip +$ mv terraform-provider-outscale_v0.1.0-rc8.1 ~/.terraform.d/plugins/linux_amd64/. ``` Installing The Provider on MacOs @@ -31,9 +31,9 @@ Installing The Provider on MacOs Download the binary and install it in ~/.terraform/plugins/darwin_amd64/. ```sh -$ wget https://github.com/outscale-dev/terraform-provider-outscale/releases/download/release-0.1.0RC8/terraform-provider-outscale_darwin_amd64_v0.1.0-rc8.zip -$ unzip terraform-provider-outscale_darwin_amd64_v0.1.0-rc8.zip -$ mv terraform-provider-outscale_v0.1.0-rc8 ~/.terraform.d/plugins/darwin_amd64/. +$ wget https://github.com/outscale-dev/terraform-provider-outscale/releases/download/release-0.1.0RC8.1/terraform-provider-outscale_darwin_amd64_v0.1.0-rc8.1.zip +$ unzip terraform-provider-outscale_darwin_amd64_v0.1.0-rc8.1.zip +$ mv terraform-provider-outscale_v0.1.0-rc8.1 ~/.terraform.d/plugins/darwin_amd64/. ``` Building The Provider @@ -43,14 +43,14 @@ Clone repository to: `$GOPATH/src/github.com/terraform-providers/terraform-provi ```sh $ mkdir -p $GOPATH/src/github.com/terraform-providers; cd $GOPATH/src/github.com/terraform-providers -$ git clone --branch release-0.1.0RC8 https://github.com/outscale-dev/terraform-provider-outscale +$ git clone --branch release-0.1.0RC8.1 https://github.com/outscale-dev/terraform-provider-outscale ``` Enter the provider directory and build the provider ```sh $ cd $GOPATH/src/github.com/terraform-providers/terraform-provider-outscale -$ go build -o terraform-provider-outscale_v0.1.0-rc8 +$ go build -o terraform-provider-outscale_v0.1.0-rc8.1 ``` Using the provider @@ -59,7 +59,7 @@ Using the provider 2. Move the plugin to the repository ~/.terraform.d/plugins/linux_amd64/. ```shell - $ mv terraform-provider-outscale_v0.1.0-rc8 ~/.terraform.d/plugins/linux_amd64/. + $ mv terraform-provider-outscale_v0.1.0-rc8.1 ~/.terraform.d/plugins/linux_amd64/. ``` 3. Execute `terraform plan`