Skip to content

Commit 16a92c5

Browse files
committed
feat(lb): add private network resource
1 parent 78ecf16 commit 16a92c5

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ func Provider(config *Config) plugin.ProviderFunc {
195195
"scaleway_lb_certificate": lb.ResourceCertificate(),
196196
"scaleway_lb_frontend": lb.ResourceFrontend(),
197197
"scaleway_lb_ip": lb.ResourceIP(),
198+
"scaleway_lb_private_network": lb.ResourcePrivateNetwork(),
198199
"scaleway_lb_route": lb.ResourceRoute(),
199200
"scaleway_mnq_nats_account": mnq.ResourceNatsAccount(),
200201
"scaleway_mnq_nats_credentials": mnq.ResourceNatsCredentials(),

internal/services/lb/helpers_lb.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,12 @@ func customizeDiffAssignFlexibleIPv6(_ context.Context, diff *schema.ResourceDif
226226

227227
return nil
228228
}
229+
230+
func ResourceLBPrivateNetworkParseID(resourceID string) (zone scw.Zone, LBID string, PNID string, err error) {
231+
idParts := strings.Split(resourceID, "/")
232+
if len(idParts) != 3 {
233+
return "", "", "", fmt.Errorf("can't parse user resource id: %s", resourceID)
234+
}
235+
236+
return scw.Zone(idParts[0]), idParts[1], idParts[2], nil
237+
}
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package lb
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
lb "github.com/scaleway/scaleway-sdk-go/api/lb/v1"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
10+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/cdf"
11+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/zonal"
14+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
15+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
16+
)
17+
18+
func ResourcePrivateNetwork() *schema.Resource {
19+
return &schema.Resource{
20+
CreateContext: resourceLbPrivateNetworkCreate,
21+
ReadContext: resourceLbPrivateNetworkRead,
22+
UpdateContext: resourceLbPrivateNetworkUpdate,
23+
DeleteContext: resourceLbPrivateNetworkDelete,
24+
Importer: &schema.ResourceImporter{
25+
StateContext: schema.ImportStatePassthroughContext,
26+
},
27+
Timeouts: &schema.ResourceTimeout{
28+
Read: schema.DefaultTimeout(defaultLbLbTimeout),
29+
Update: schema.DefaultTimeout(defaultLbLbTimeout),
30+
Delete: schema.DefaultTimeout(defaultLbLbTimeout),
31+
Default: schema.DefaultTimeout(defaultLbLbTimeout),
32+
},
33+
SchemaVersion: 0,
34+
Schema: map[string]*schema.Schema{
35+
"lb_id": {
36+
Type: schema.TypeString,
37+
Required: true,
38+
ForceNew: true,
39+
Description: "The load-balancer ID to attach the private network to",
40+
},
41+
"private_network_id": {
42+
Type: schema.TypeString,
43+
Required: true,
44+
ForceNew: true,
45+
Description: "The private network ID to attach",
46+
},
47+
"ipam_ip_ids": {
48+
Type: schema.TypeList,
49+
Elem: &schema.Schema{
50+
Type: schema.TypeString,
51+
},
52+
MaxItems: 1,
53+
Optional: true,
54+
Computed: true,
55+
ForceNew: true,
56+
Description: "IPAM ID of a pre-reserved IP address to assign to the Load Balancer on this Private Network",
57+
},
58+
"zone": zonal.Schema(),
59+
// Computed
60+
"status": {
61+
Type: schema.TypeString,
62+
Computed: true,
63+
Description: "The status of private network connection",
64+
},
65+
"created_at": {
66+
Type: schema.TypeString,
67+
Computed: true,
68+
Description: "The date and time of the creation of the private network connection",
69+
},
70+
"updated_at": {
71+
Type: schema.TypeString,
72+
Computed: true,
73+
Description: "The date and time of the last update of the private network connection",
74+
},
75+
"project_id": account.ProjectIDSchema(),
76+
},
77+
CustomizeDiff: cdf.LocalityCheck("lb_id", "private_network_id"),
78+
}
79+
}
80+
81+
func resourceLbPrivateNetworkCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
82+
lbAPI, zone, err := lbAPIWithZone(d, m)
83+
if err != nil {
84+
return diag.FromErr(err)
85+
}
86+
87+
_, err = waitForLB(ctx, lbAPI, zone, zonal.ExpandID(d.Get("lb_id").(string)).ID, d.Timeout(schema.TimeoutCreate))
88+
if err != nil {
89+
return diag.FromErr(err)
90+
}
91+
92+
attach, err := lbAPI.AttachPrivateNetwork(&lb.ZonedAPIAttachPrivateNetworkRequest{
93+
Zone: zone,
94+
LBID: zonal.ExpandID(d.Get("lb_id").(string)).ID,
95+
PrivateNetworkID: regional.ExpandID(d.Get("private_network_id").(string)).ID,
96+
IpamIDs: types.ExpandStrings(d.Get("ipam_ip_ids")),
97+
}, scw.WithContext(ctx))
98+
if err != nil {
99+
return diag.FromErr(err)
100+
}
101+
102+
d.SetId(
103+
zonal.NewNestedIDString(
104+
zone,
105+
attach.LB.ID,
106+
attach.PrivateNetworkID,
107+
),
108+
)
109+
110+
return resourceLbPrivateNetworkRead(ctx, d, m)
111+
}
112+
113+
func resourceLbPrivateNetworkRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
114+
lbAPI, zone, err := lbAPIWithZone(d, m)
115+
if err != nil {
116+
return diag.FromErr(err)
117+
}
118+
119+
zone, LBID, PNID, err := ResourceLBPrivateNetworkParseID(d.Id())
120+
if err != nil {
121+
return diag.FromErr(err)
122+
}
123+
124+
privateNetworks, err := waitForPrivateNetworks(ctx, lbAPI, zone, LBID, d.Timeout(schema.TimeoutRead))
125+
if err != nil {
126+
if httperrors.Is404(err) {
127+
d.SetId("")
128+
129+
return nil
130+
}
131+
132+
return diag.FromErr(err)
133+
}
134+
135+
var foundPN *lb.PrivateNetwork
136+
for _, pn := range privateNetworks {
137+
if pn.PrivateNetworkID == PNID {
138+
foundPN = pn
139+
break
140+
}
141+
}
142+
143+
if foundPN == nil {
144+
d.SetId("")
145+
return nil
146+
}
147+
148+
_ = d.Set("private_network_id", foundPN.PrivateNetworkID)
149+
_ = d.Set("lb_id", foundPN.LB.ID)
150+
_ = d.Set("ipam_ip_ids", foundPN.IpamIDs)
151+
_ = d.Set("status", foundPN.Status)
152+
_ = d.Set("created_at", foundPN.CreatedAt)
153+
_ = d.Set("updated_at", foundPN.UpdatedAt)
154+
_ = d.Set("zone", zone)
155+
_ = d.Set("project_id", foundPN.LB.ProjectID)
156+
157+
return nil
158+
}
159+
160+
func resourceLbPrivateNetworkUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
161+
return resourceLbPrivateNetworkRead(ctx, d, m)
162+
}
163+
164+
func resourceLbPrivateNetworkDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
165+
lbAPI, zone, err := lbAPIWithZone(d, m)
166+
if err != nil {
167+
return diag.FromErr(err)
168+
}
169+
170+
zone, LBID, PNID, err := ResourceLBPrivateNetworkParseID(d.Id())
171+
if err != nil {
172+
return diag.FromErr(err)
173+
}
174+
175+
err = lbAPI.DetachPrivateNetwork(&lb.ZonedAPIDetachPrivateNetworkRequest{
176+
Zone: zone,
177+
LBID: LBID,
178+
PrivateNetworkID: PNID,
179+
}, scw.WithContext(ctx))
180+
if err != nil && !httperrors.Is404(err) {
181+
return diag.FromErr(err)
182+
}
183+
184+
return nil
185+
}

0 commit comments

Comments
 (0)