Skip to content

Commit

Permalink
feat(lb): add IP resource
Browse files Browse the repository at this point in the history
Signed-off-by: Patrik Cyvoct <[email protected]>
  • Loading branch information
Sh4d1 committed Apr 15, 2020
1 parent cfe1e6f commit fce01e9
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 7 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
26 changes: 21 additions & 5 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 @@ -36,10 +37,17 @@ func resourceScalewayLbBeta() *schema.Resource {
Optional: true,
Description: "Array of tags to associate with the load-balancer",
},
"keep_ip_on_delete": {
Type: schema.TypeBool,
Computed: true,
},
"ip_id": {
Type: schema.TypeString,
Computed: true,
Description: "The load-balance public IP ID",
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The load-balance public IP ID",
ForceNew: true,
DiffSuppressFunc: diffSuppressFuncLocality,
},
"ip_address": {
Type: schema.TypeString,
Expand All @@ -64,6 +72,14 @@ func resourceScalewayLbBetaCreate(d *schema.ResourceData, m interface{}) error {
Name: expandOrGenerateString(d.Get("name"), "lb"),
Type: d.Get("type").(string),
}

if ipID, ok := d.GetOk("ip_id"); ok {
createReq.IPID = scw.StringPtr(expandID(ipID.(string)))
_ = d.Set("keep_ip_on_delete", true)
} else {
_ = d.Set("keep_ip_on_delete", false)
}

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 +128,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 @@ -152,7 +168,7 @@ func resourceScalewayLbBetaDelete(d *schema.ResourceData, m interface{}) error {
Region: region,
LbID: ID,
// This parameter will probably be breaking change when ip pre reservation will exist.
ReleaseIP: true,
ReleaseIP: !d.Get("keep_ip_on_delete").(bool),
})

if err != nil && !is404Error(err) {
Expand Down
41 changes: 41 additions & 0 deletions scaleway/resource_lb_beta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,47 @@ 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_ip_beta ip01 {
reverse = "reverse.com" # force the refresh of the IP
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayLbIPBetaExists("scaleway_lb_ip_beta.ip01"),
resource.TestCheckResourceAttr("scaleway_lb_ip_beta.ip01", "lb_id", ""),
),
},
},
})
}

func testAccCheckScalewayLbBetaExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down
137 changes: 137 additions & 0 deletions scaleway/resource_lb_ip_beta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
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 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),
}
if reverse, ok := d.GetOk("reverse"); ok {
createReq.Reverse = scw.StringPtr(reverse.(string))
}
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)
if res.LbID != nil {
_ = d.Set("lb_id", *res.LbID)
} else {
_ = d.Set("lb_id", "")
}

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: scw.StringPtr(d.Get("reverse").(string)),
}

_, 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
}
98 changes: 98 additions & 0 deletions scaleway/resource_lb_ip_beta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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"
)

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
}
10 changes: 8 additions & 2 deletions website/docs/r/lb_beta.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ Creates and manages Scaleway Load-Balancers. For more information, see [the docu
### Basic

```hcl
resource "scaleway_lb_ip_beta" "ip" {
}
resource "scaleway_lb_beta" "base" {
ip_id = scaleway_lb_ip_beta.ip.id
region = "fr-par"
type = "LB-S"
}
Expand All @@ -26,6 +30,10 @@ resource "scaleway_lb_beta" "base" {

The following arguments are supported:

- `ip_id` - (Required) The ID of the associated IP.

~> **Important:** Updates to `ip_id` will recreate the load-balancer.

- `type` - (Required) The type of the load-balancer. For now only `LB-S` is available

~> **Important:** Updates to `type` will recreate the load-balancer.
Expand All @@ -38,13 +46,11 @@ The following arguments are supported:

- `organization_id` - (Defaults to [provider](../index.html#organization_id) `organization_id`) The ID of the organization the load-balancer is associated with.


## Attributes Reference

In addition to all arguments above, the following attributes are exported:

- `id` - The ID of the load-balancer.
- `ip_id` - The load-balance public IP ID
- `ip_address` - The load-balance public IP Address


Expand Down
Loading

0 comments on commit fce01e9

Please sign in to comment.