Skip to content

Commit

Permalink
feat(lb): add IP resource (#452)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sh4d1 authored Apr 17, 2020
1 parent cfe1e6f commit 93d6e63
Show file tree
Hide file tree
Showing 7 changed files with 387 additions and 21 deletions.
1 change: 1 addition & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ func Provider() terraform.ResourceProvider {
"scaleway_k8s_cluster_beta": resourceScalewayK8SClusterBeta(),
"scaleway_k8s_pool_beta": resourceScalewayK8SPoolBeta(),
"scaleway_lb_beta": resourceScalewayLbBeta(),
"scaleway_lb_ip_beta": resourceScalewayLbIPBeta(),
"scaleway_lb_backend_beta": resourceScalewayLbBackendBeta(),
"scaleway_lb_certificate_beta": resourceScalewayLbCertificateBeta(),
"scaleway_lb_frontend_beta": resourceScalewayLbFrontendBeta(),
Expand Down
20 changes: 12 additions & 8 deletions scaleway/resource_lb_beta.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package scaleway
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
lb "github.com/scaleway/scaleway-sdk-go/api/lb/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func resourceScalewayLbBeta() *schema.Resource {
Expand Down Expand Up @@ -37,9 +38,11 @@ func resourceScalewayLbBeta() *schema.Resource {
Description: "Array of tags to associate with the load-balancer",
},
"ip_id": {
Type: schema.TypeString,
Computed: true,
Description: "The load-balance public IP ID",
Type: schema.TypeString,
Required: true,
Description: "The load-balance public IP ID",
ForceNew: true,
DiffSuppressFunc: diffSuppressFuncLocality,
},
"ip_address": {
Type: schema.TypeString,
Expand All @@ -60,10 +63,12 @@ func resourceScalewayLbBetaCreate(d *schema.ResourceData, m interface{}) error {

createReq := &lb.CreateLbRequest{
Region: region,
IPID: scw.StringPtr(expandID(d.Get("ip_id").(string))),
OrganizationID: d.Get("organization_id").(string),
Name: expandOrGenerateString(d.Get("name"), "lb"),
Type: d.Get("type").(string),
}

if raw, ok := d.GetOk("tags"); ok {
for _, tag := range raw.([]interface{}) {
createReq.Tags = append(createReq.Tags, tag.(string))
Expand Down Expand Up @@ -112,7 +117,7 @@ func resourceScalewayLbBetaRead(d *schema.ResourceData, m interface{}) error {
_ = d.Set("organization_id", res.OrganizationID)
_ = d.Set("tags", res.Tags)
_ = d.Set("type", res.Type)
_ = d.Set("ip_id", res.IP[0].ID)
_ = d.Set("ip_id", newRegionalId(region, res.IP[0].ID))
_ = d.Set("ip_address", res.IP[0].IPAddress)

return nil
Expand Down Expand Up @@ -149,10 +154,9 @@ func resourceScalewayLbBetaDelete(d *schema.ResourceData, m interface{}) error {
}

err = lbAPI.DeleteLb(&lb.DeleteLbRequest{
Region: region,
LbID: ID,
// This parameter will probably be breaking change when ip pre reservation will exist.
ReleaseIP: true,
Region: region,
LbID: ID,
ReleaseIP: false,
})

if err != nil && !is404Error(err) {
Expand Down
30 changes: 19 additions & 11 deletions scaleway/resource_lb_beta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,41 +43,49 @@ func testSweepLB(region string) error {
return nil
}

func TestAccScalewayLbBeta(t *testing.T) {
func TestAccScalewayLbAndIPBeta(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckScalewayLbBetaDestroy,
Steps: []resource.TestStep{
{
Config: `
resource scaleway_lb_ip_beta ip01 {
}
resource scaleway_lb_beta lb01 {
ip_id = scaleway_lb_ip_beta.ip01.id
name = "test-lb"
type = "lb-s"
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbBetaExists("scaleway_lb_beta.lb01"),
testAccCheckScalewayLbIPBetaExists("scaleway_lb_ip_beta.ip01"),
resource.TestCheckResourceAttr("scaleway_lb_beta.lb01", "name", "test-lb"),
testCheckResourceAttrUUID("scaleway_lb_beta.lb01", "ip_id"),
testCheckResourceAttrIPv4("scaleway_lb_beta.lb01", "ip_address"),
resource.TestCheckResourceAttrPair("scaleway_lb_beta.lb01", "ip_id", "scaleway_lb_ip_beta.ip01", "id"),
),
},
{
Config: `
resource scaleway_lb_beta lb01 {
name = "test-lb"
type = "lb-s"
tags = ["tag1", "tag2"]
resource scaleway_lb_ip_beta ip01 {
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbBetaExists("scaleway_lb_beta.lb01"),
resource.TestCheckResourceAttr("scaleway_lb_beta.lb01", "name", "test-lb"),
resource.TestCheckResourceAttr("scaleway_lb_beta.lb01", "tags.0", "tag1"),
resource.TestCheckResourceAttr("scaleway_lb_beta.lb01", "tags.1", "tag2"),
testCheckResourceAttrUUID("scaleway_lb_beta.lb01", "ip_id"),
testCheckResourceAttrIPv4("scaleway_lb_beta.lb01", "ip_address"),
testAccCheckScalewayLbIPBetaExists("scaleway_lb_ip_beta.ip01"),
),
},
{
Config: `
resource scaleway_lb_ip_beta ip01 {
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbIPBetaExists("scaleway_lb_ip_beta.ip01"),
resource.TestCheckResourceAttr("scaleway_lb_ip_beta.ip01", "lb_id", ""),
),
},
},
Expand Down
131 changes: 131 additions & 0 deletions scaleway/resource_lb_ip_beta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package scaleway

import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
lb "github.com/scaleway/scaleway-sdk-go/api/lb/v1"
)

func resourceScalewayLbIPBeta() *schema.Resource {
return &schema.Resource{
Create: resourceScalewayLbIPBetaCreate,
Read: resourceScalewayLbIPBetaRead,
Update: resourceScalewayLbIPBetaUpdate,
Delete: resourceScalewayLbIPBetaDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
SchemaVersion: 0,
Schema: map[string]*schema.Schema{
"reverse": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The reverse domain name for this IP",
},
"region": regionSchema(),
"organization_id": organizationIDSchema(),
// Computed
"ip_address": {
Type: schema.TypeString,
Computed: true,
Description: "The load-balance public IP address",
},
"lb_id": {
Type: schema.TypeString,
Computed: true,
Description: "The ID of the loadbalancer attached to this IP, if any",
},
},
}
}

func resourceScalewayLbIPBetaCreate(d *schema.ResourceData, m interface{}) error {
lbAPI, region, err := lbAPIWithRegion(d, m)
if err != nil {
return err
}

createReq := &lb.CreateIPRequest{
Region: region,
OrganizationID: d.Get("organization_id").(string),
Reverse: expandStringPtr(d.Get("reverse")),
}

res, err := lbAPI.CreateIP(createReq)
if err != nil {
return err
}

d.SetId(newRegionalId(region, res.ID))

return resourceScalewayLbIPBetaRead(d, m)
}

func resourceScalewayLbIPBetaRead(d *schema.ResourceData, m interface{}) error {
lbAPI, region, ID, err := lbAPIWithRegionAndID(m, d.Id())
if err != nil {
return err
}

res, err := lbAPI.GetIP(&lb.GetIPRequest{
Region: region,
IPID: ID,
})

if err != nil {
if is404Error(err) {
d.SetId("")
return nil
}
return err
}

_ = d.Set("region", string(region))
_ = d.Set("organization_id", res.OrganizationID)
_ = d.Set("ip_id", res.ID)
_ = d.Set("ip_address", res.IPAddress)
_ = d.Set("reverse", res.Reverse)
_ = d.Set("lb_ip", flattenStringPtr(res.LbID))

return nil
}

func resourceScalewayLbIPBetaUpdate(d *schema.ResourceData, m interface{}) error {
lbAPI, region, ID, err := lbAPIWithRegionAndID(m, d.Id())
if err != nil {
return err
}

if d.HasChange("reverse") {
req := &lb.UpdateIPRequest{
Region: region,
IPID: ID,
Reverse: expandStringPtr(d.Get("reverse")),
}

_, err = lbAPI.UpdateIP(req)
if err != nil {
return err
}
}

return resourceScalewayLbIPBetaRead(d, m)
}

func resourceScalewayLbIPBetaDelete(d *schema.ResourceData, m interface{}) error {
lbAPI, region, ID, err := lbAPIWithRegionAndID(m, d.Id())
if err != nil {
return err
}

err = lbAPI.ReleaseIP(&lb.ReleaseIPRequest{
Region: region,
IPID: ID,
})

if err != nil && !is404Error(err) {
return err
}

return nil
}
133 changes: 133 additions & 0 deletions scaleway/resource_lb_ip_beta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package scaleway

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/scaleway/scaleway-sdk-go/api/lb/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func init() {
resource.AddTestSweepers("scaleway_lb_ip_beta", &resource.Sweeper{
Name: "scaleway_lb_ip_beta",
F: testSweepLBIP,
})
}

func testSweepLBIP(region string) error {
scwClient, err := sharedClientForRegion(region)
if err != nil {
return fmt.Errorf("error getting client in sweeper: %s", err)
}
lbAPI := lb.NewAPI(scwClient)

l.Debugf("sweeper: destroying the lb ips in (%s)", region)
listIPs, err := lbAPI.ListIPs(&lb.ListIPsRequest{}, scw.WithAllPages())
if err != nil {
return fmt.Errorf("error listing lb ips in (%s) in sweeper: %s", region, err)
}

for _, ip := range listIPs.IPs {
if ip.LbID == nil {
err := lbAPI.ReleaseIP(&lb.ReleaseIPRequest{
IPID: ip.ID,
})
if err != nil {
return fmt.Errorf("error deleting lb ip in sweeper: %s", err)
}
}
}

return nil
}

func TestAccScalewayLbIPBeta(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckScalewayLbIPBetaDestroy,
Steps: []resource.TestStep{
{
Config: `
resource scaleway_lb_ip_beta ip01 {
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbIPBetaExists("scaleway_lb_ip_beta.ip01"),
testCheckResourceAttrIPv4("scaleway_lb_ip_beta.ip01", "ip_address"),
resource.TestCheckResourceAttrSet("scaleway_lb_ip_beta.ip01", "reverse"),
),
},
{
Config: `
resource scaleway_lb_ip_beta ip01 {
reverse = "myreverse.com"
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbIPBetaExists("scaleway_lb_ip_beta.ip01"),
testCheckResourceAttrIPv4("scaleway_lb_ip_beta.ip01", "ip_address"),
resource.TestCheckResourceAttr("scaleway_lb_ip_beta.ip01", "reverse", "myreverse.com"),
),
},
},
})
}

func testAccCheckScalewayLbIPBetaExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("resource not found: %s", n)
}

lbAPI, region, ID, err := lbAPIWithRegionAndID(testAccProvider.Meta(), rs.Primary.ID)
if err != nil {
return err
}

_, err = lbAPI.GetIP(&lb.GetIPRequest{
IPID: ID,
Region: region,
})

if err != nil {
return err
}

return nil
}
}

func testAccCheckScalewayLbIPBetaDestroy(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "scaleway_lb_ip_beta" {
continue
}

lbAPI, region, ID, err := lbAPIWithRegionAndID(testAccProvider.Meta(), rs.Primary.ID)
if err != nil {
return err
}

_, err = lbAPI.GetIP(&lb.GetIPRequest{
Region: region,
IPID: ID,
})

// If no error resource still exist
if err == nil {
return fmt.Errorf("IP (%s) still exists", rs.Primary.ID)
}

// Unexpected api error we return it
if !is404Error(err) {
return err
}
}

return nil
}
Loading

0 comments on commit 93d6e63

Please sign in to comment.