Skip to content

Commit eba39d1

Browse files
committed
feat(vpcgw): add support for vpc public gateway ip
1 parent 2865bf2 commit eba39d1

4 files changed

+653
-0
lines changed

scaleway/provider.go

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
8686
"scaleway_rdb_user": resourceScalewayRdbUser(),
8787
"scaleway_object_bucket": resourceScalewayObjectBucket(),
8888
"scaleway_vpc_public_gateway": resourceScalewayVPCPublicGateway(),
89+
"scaleway_vpc_public_gateway_ip": resourceScalewayVPCPublicGatewayIP(),
8990
"scaleway_vpc_private_network": resourceScalewayVPCPrivateNetwork(),
9091
},
9192

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package scaleway
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
vpcgw "github.com/scaleway/scaleway-sdk-go/api/vpcgw/v1beta1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
)
12+
13+
func resourceScalewayVPCPublicGatewayIP() *schema.Resource {
14+
return &schema.Resource{
15+
CreateContext: resourceScalewayVPCPublicGatewayIPCreate,
16+
ReadContext: resourceScalewayVPCPublicGatewayIPRead,
17+
UpdateContext: resourceScalewayVPCPublicGatewayIPUpdate,
18+
DeleteContext: resourceScalewayVPCPublicGatewayIPDelete,
19+
Importer: &schema.ResourceImporter{
20+
StateContext: schema.ImportStatePassthroughContext,
21+
},
22+
SchemaVersion: 0,
23+
Schema: map[string]*schema.Schema{
24+
"ip_id": {
25+
Type: schema.TypeString,
26+
Optional: true,
27+
Computed: true,
28+
Description: "attach an existing IP to the gateway",
29+
},
30+
"tags": {
31+
Type: schema.TypeList,
32+
Optional: true,
33+
Description: "The tags associated with public gateway",
34+
Elem: &schema.Schema{
35+
Type: schema.TypeString,
36+
},
37+
},
38+
"project_id": projectIDSchema(),
39+
"zone": zoneSchema(),
40+
// Computed elements
41+
"organization_id": organizationIDSchema(),
42+
"created_at": {
43+
Type: schema.TypeString,
44+
Computed: true,
45+
Description: "The date and time of the creation of the public gateway",
46+
},
47+
"updated_at": {
48+
Type: schema.TypeString,
49+
Computed: true,
50+
Description: "The date and time of the last update of the public gateway",
51+
},
52+
},
53+
}
54+
}
55+
56+
func resourceScalewayVPCPublicGatewayIPCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
57+
vpcgwAPI, zone, err := vpcgwAPIWithZone(d, meta)
58+
if err != nil {
59+
return diag.FromErr(err)
60+
}
61+
62+
req := &vpcgw.CreateIPRequest{
63+
Tags: expandStrings(d.Get("tags")),
64+
ProjectID: d.Get("project_id").(string),
65+
Zone: zone,
66+
}
67+
68+
res, err := vpcgwAPI.CreateIP(req, scw.WithContext(ctx))
69+
if err != nil {
70+
return diag.FromErr(err)
71+
}
72+
73+
d.SetId(newZonedIDString(zone, res.ID))
74+
75+
return resourceScalewayVPCPublicGatewayIPRead(ctx, d, meta)
76+
}
77+
78+
func resourceScalewayVPCPublicGatewayIPRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
79+
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(meta, d.Id())
80+
if err != nil {
81+
return diag.FromErr(err)
82+
}
83+
84+
ip, err := vpcgwAPI.GetIP(&vpcgw.GetIPRequest{
85+
IPID: ID,
86+
Zone: zone,
87+
}, scw.WithContext(ctx))
88+
if err != nil {
89+
if is404Error(err) {
90+
d.SetId("")
91+
return nil
92+
}
93+
return diag.FromErr(err)
94+
}
95+
96+
_ = d.Set("organization_id", ip.OrganizationID)
97+
_ = d.Set("project_id", ip.ProjectID)
98+
_ = d.Set("created_at", ip.CreatedAt.Format(time.RFC3339))
99+
_ = d.Set("updated_at", ip.UpdatedAt.Format(time.RFC3339))
100+
_ = d.Set("zone", zone)
101+
_ = d.Set("tags", ip.Tags)
102+
_ = d.Set("ip_id", ip.ID)
103+
104+
return nil
105+
}
106+
107+
func resourceScalewayVPCPublicGatewayIPUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
108+
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(meta, d.Id())
109+
if err != nil {
110+
return diag.FromErr(err)
111+
}
112+
113+
if d.HasChanges("tags") {
114+
updateRequest := &vpcgw.UpdateIPRequest{
115+
IPID: ID,
116+
Zone: zone,
117+
Tags: scw.StringsPtr(expandStrings(d.Get("tags"))),
118+
}
119+
120+
_, err = vpcgwAPI.UpdateIP(updateRequest, scw.WithContext(ctx))
121+
if err != nil {
122+
return diag.FromErr(err)
123+
}
124+
}
125+
126+
return resourceScalewayVPCPublicGatewayIPRead(ctx, d, meta)
127+
}
128+
129+
func resourceScalewayVPCPublicGatewayIPDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
130+
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(meta, d.Id())
131+
if err != nil {
132+
return diag.FromErr(err)
133+
}
134+
135+
err = vpcgwAPI.DeleteIP(&vpcgw.DeleteIPRequest{
136+
IPID: ID,
137+
Zone: zone,
138+
}, scw.WithContext(ctx))
139+
140+
if err != nil && !is404Error(err) {
141+
return diag.FromErr(err)
142+
}
143+
144+
return nil
145+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package scaleway
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
vpcgw "github.com/scaleway/scaleway-sdk-go/api/vpcgw/v1beta1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
)
12+
13+
func init() {
14+
resource.AddTestSweepers("scaleway_vpc_public_gateway_ip", &resource.Sweeper{
15+
Name: "scaleway_vpc_public_gateway_ip",
16+
F: testSweepVPCPublicGatewayIP,
17+
})
18+
}
19+
20+
func testSweepVPCPublicGatewayIP(_ string) error {
21+
return sweepZones(scw.AllZones, func(scwClient *scw.Client, zone scw.Zone) error {
22+
vpcgwAPI := vpcgw.NewAPI(scwClient)
23+
l.Debugf("sweeper: destroying the public gateways ip in (%s)", zone)
24+
25+
listIPResponse, err := vpcgwAPI.ListIPs(&vpcgw.ListIPsRequest{
26+
Zone: zone,
27+
}, scw.WithAllPages())
28+
if err != nil {
29+
return fmt.Errorf("error listing public gateway ip in sweeper: %s", err)
30+
}
31+
32+
for _, ip := range listIPResponse.IPs {
33+
err := vpcgwAPI.DeleteIP(&vpcgw.DeleteIPRequest{
34+
Zone: zone,
35+
IPID: ip.ID,
36+
})
37+
if err != nil {
38+
return fmt.Errorf("error deleting public gateway ip in sweeper: %s", err)
39+
}
40+
}
41+
return nil
42+
})
43+
}
44+
45+
func TestAccScalewayVPCPublicGatewayIP_Basic(t *testing.T) {
46+
tt := NewTestTools(t)
47+
defer tt.Cleanup()
48+
49+
resource.ParallelTest(t, resource.TestCase{
50+
PreCheck: func() { testAccPreCheck(t) },
51+
ProviderFactories: tt.ProviderFactories,
52+
CheckDestroy: testAccCheckScalewayVPCPublicGatewayIPDestroy(tt),
53+
Steps: []resource.TestStep{
54+
{
55+
Config: fmt.Sprintf(`
56+
resource scaleway_vpc_public_gateway_ip main {
57+
}
58+
`),
59+
Check: resource.ComposeTestCheckFunc(
60+
testAccCheckScalewayVPCPublicGatewayIPExists(
61+
tt,
62+
"scaleway_vpc_public_gateway_ip.main",
63+
),
64+
),
65+
},
66+
{
67+
Config: fmt.Sprintf(`
68+
resource scaleway_vpc_public_gateway_ip main {
69+
tags = ["tag0", "tag1"]
70+
}
71+
`),
72+
Check: resource.ComposeTestCheckFunc(
73+
testAccCheckScalewayVPCPublicGatewayIPExists(
74+
tt,
75+
"scaleway_vpc_public_gateway_ip.main",
76+
),
77+
resource.TestCheckResourceAttr(
78+
"scaleway_vpc_public_gateway_ip.main",
79+
"tags.0",
80+
"tag0",
81+
),
82+
resource.TestCheckResourceAttr(
83+
"scaleway_vpc_public_gateway_ip.main",
84+
"tags.1",
85+
"tag1",
86+
),
87+
),
88+
},
89+
},
90+
})
91+
}
92+
93+
func testAccCheckScalewayVPCPublicGatewayIPExists(tt *TestTools, n string) resource.TestCheckFunc {
94+
return func(s *terraform.State) error {
95+
rs, ok := s.RootModule().Resources[n]
96+
if !ok {
97+
return fmt.Errorf("resource not found: %s", n)
98+
}
99+
100+
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
101+
if err != nil {
102+
return err
103+
}
104+
105+
_, err = vpcgwAPI.GetIP(&vpcgw.GetIPRequest{
106+
IPID: ID,
107+
Zone: zone,
108+
})
109+
110+
if err != nil {
111+
return err
112+
}
113+
114+
return nil
115+
}
116+
}
117+
118+
func testAccCheckScalewayVPCPublicGatewayIPDestroy(tt *TestTools) resource.TestCheckFunc {
119+
return func(state *terraform.State) error {
120+
for _, rs := range state.RootModule().Resources {
121+
if rs.Type != "scaleway_vpc_public_gateway_ip" {
122+
continue
123+
}
124+
125+
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
126+
if err != nil {
127+
return err
128+
}
129+
130+
_, err = vpcgwAPI.GetIP(&vpcgw.GetIPRequest{
131+
IPID: ID,
132+
Zone: zone,
133+
})
134+
135+
if err == nil {
136+
return fmt.Errorf(
137+
"VPC public gateway ip %s still exists",
138+
rs.Primary.ID,
139+
)
140+
}
141+
142+
// Unexpected api error we return it
143+
if !is404Error(err) {
144+
return err
145+
}
146+
}
147+
148+
return nil
149+
}
150+
}

0 commit comments

Comments
 (0)