Skip to content

Commit 7c4da1c

Browse files
committed
feat(apple-silicon): add support vpc
1 parent 354607f commit 7c4da1c

File tree

5 files changed

+172
-2
lines changed

5 files changed

+172
-2
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
github.com/nats-io/jwt/v2 v2.7.3
3131
github.com/nats-io/nats.go v1.37.0
3232
github.com/robfig/cron/v3 v3.0.1
33-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30.0.20250115101541-adcf20ac0a4e
33+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31.0.20250128135513-ad2f1fb6c4b9
3434
github.com/stretchr/testify v1.9.0
3535
golang.org/x/crypto v0.31.0
3636
gopkg.in/dnaeon/go-vcr.v3 v3.2.0

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30.0.20241129094524-023aa8142bc1
284284
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30.0.20241129094524-023aa8142bc1/go.mod h1:kAoejOVBg1E/aVAR6IwKWEmbLCEg2IXklzPAkxzAaXA=
285285
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30.0.20250115101541-adcf20ac0a4e h1:jkaT8NRDr9XNOtXVF743DPgOpp50xDEIwR/S1AWQCWk=
286286
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30.0.20250115101541-adcf20ac0a4e/go.mod h1:kzh+BSAvpoyHHdHBCDhmSWtBc1NbLMZ2lWHqnBoxFks=
287+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31 h1:Fj7jPyu9TQjqfXcLylINK5PANSzOWXIX4QtGmfp67AY=
288+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31/go.mod h1:kzh+BSAvpoyHHdHBCDhmSWtBc1NbLMZ2lWHqnBoxFks=
289+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31.0.20250128135513-ad2f1fb6c4b9 h1:qvgJcZjBgpQ6AkNA4yBtYKa9QJ4a0MME603X+Fe81Sg=
290+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31.0.20250128135513-ad2f1fb6c4b9/go.mod h1:kzh+BSAvpoyHHdHBCDhmSWtBc1NbLMZ2lWHqnBoxFks=
287291
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
288292
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
289293
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=

internal/services/applesilicon/server.go

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package applesilicon
22

33
import (
44
"context"
5+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
6+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/verify"
58
"time"
69

710
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -47,6 +50,55 @@ func ResourceServer() *schema.Resource {
4750
Default: false,
4851
Description: "Whether or not to enable VPC access",
4952
},
53+
"private_network": {
54+
Type: schema.TypeSet,
55+
Optional: true,
56+
Description: "The private networks to attach to the server",
57+
Elem: &schema.Resource{
58+
Schema: map[string]*schema.Schema{
59+
"id": {
60+
Type: schema.TypeString,
61+
Description: "The private network ID",
62+
Required: true,
63+
ValidateDiagFunc: verify.IsUUIDorUUIDWithLocality(),
64+
StateFunc: func(i interface{}) string {
65+
return locality.ExpandID(i.(string))
66+
},
67+
},
68+
"ipam_ip_ids": {
69+
Type: schema.TypeList,
70+
Optional: true,
71+
Computed: true,
72+
Elem: &schema.Schema{
73+
Type: schema.TypeString,
74+
ValidateDiagFunc: verify.IsUUIDorUUIDWithLocality(),
75+
},
76+
Description: "List of IPAM IP IDs to attach to the server",
77+
},
78+
// computed
79+
"vlan": {
80+
Type: schema.TypeInt,
81+
Computed: true,
82+
Description: "The VLAN ID associated to the private network",
83+
},
84+
"status": {
85+
Type: schema.TypeString,
86+
Computed: true,
87+
Description: "The private network status",
88+
},
89+
"created_at": {
90+
Type: schema.TypeString,
91+
Computed: true,
92+
Description: "The date and time of the creation of the private network",
93+
},
94+
"updated_at": {
95+
Type: schema.TypeString,
96+
Computed: true,
97+
Description: "The date and time of the last update of the private network",
98+
},
99+
},
100+
},
101+
},
50102
// Computed
51103
"ip": {
52104
Type: schema.TypeString,
@@ -106,6 +158,7 @@ func ResourceAppleSiliconServerCreate(ctx context.Context, d *schema.ResourceDat
106158
}
107159

108160
res, err := asAPI.CreateServer(createReq, scw.WithContext(ctx))
161+
109162
if err != nil {
110163
return diag.FromErr(err)
111164
}
@@ -117,6 +170,20 @@ func ResourceAppleSiliconServerCreate(ctx context.Context, d *schema.ResourceDat
117170
return diag.FromErr(err)
118171
}
119172

173+
if pn, ok := d.GetOk("private_network"); ok {
174+
privateNetworkAPI := applesilicon.NewPrivateNetworkAPI(meta.ExtractScwClient(m))
175+
req := &applesilicon.PrivateNetworkAPISetServerPrivateNetworksRequest{
176+
Zone: zone,
177+
ServerID: res.ID,
178+
PerPrivateNetworkIpamIPIDs: expandPrivateNetworks(pn),
179+
}
180+
_, err := privateNetworkAPI.SetServerPrivateNetworks(req, scw.WithContext(ctx))
181+
if err != nil {
182+
return diag.FromErr(err)
183+
}
184+
_, err = waitForAppleSiliconPrivateNetworkServer(ctx, privateNetworkAPI, zone, res.ID, d.Timeout(schema.TimeoutCreate))
185+
}
186+
120187
return ResourceAppleSiliconServerRead(ctx, d, m)
121188
}
122189

@@ -126,6 +193,8 @@ func ResourceAppleSiliconServerRead(ctx context.Context, d *schema.ResourceData,
126193
return diag.FromErr(err)
127194
}
128195

196+
privateNetworkAPI := applesilicon.NewPrivateNetworkAPI(meta.ExtractScwClient(m))
197+
129198
res, err := asAPI.GetServer(&applesilicon.GetServerRequest{
130199
Zone: zone,
131200
ServerID: ID,
@@ -147,10 +216,21 @@ func ResourceAppleSiliconServerRead(ctx context.Context, d *schema.ResourceData,
147216
_ = d.Set("ip", res.IP.String())
148217
_ = d.Set("vnc_url", res.VncURL)
149218
_ = d.Set("vpc_status", res.VpcStatus)
150-
151219
_ = d.Set("zone", res.Zone.String())
152220
_ = d.Set("organization_id", res.OrganizationID)
153221
_ = d.Set("project_id", res.ProjectID)
222+
listPrivateNetworks, err := privateNetworkAPI.ListServerPrivateNetworks(&applesilicon.PrivateNetworkAPIListServerPrivateNetworksRequest{
223+
Zone: res.Zone,
224+
ServerID: &res.ID,
225+
})
226+
if err != nil {
227+
return diag.FromErr(err)
228+
}
229+
pnRegion, err := res.Zone.Region()
230+
if err != nil {
231+
return diag.FromErr(err)
232+
}
233+
_ = d.Set("private_network", flattenPrivateNetworks(pnRegion, listPrivateNetworks.ServerPrivateNetworks))
154234

155235
return nil
156236
}
@@ -161,6 +241,8 @@ func ResourceAppleSiliconServerUpdate(ctx context.Context, d *schema.ResourceDat
161241
return diag.FromErr(err)
162242
}
163243

244+
privateNetworkAPI := applesilicon.NewPrivateNetworkAPI(meta.ExtractScwClient(m))
245+
164246
req := &applesilicon.UpdateServerRequest{
165247
Zone: zone,
166248
ServerID: ID,
@@ -173,6 +255,26 @@ func ResourceAppleSiliconServerUpdate(ctx context.Context, d *schema.ResourceDat
173255
if d.HasChange("enable_vpc") {
174256
enableVpc := d.Get("enable_vpc").(bool)
175257
req.EnableVpc = &enableVpc
258+
if !enableVpc {
259+
listPrivateNetworks, err := privateNetworkAPI.ListServerPrivateNetworks(&applesilicon.PrivateNetworkAPIListServerPrivateNetworksRequest{
260+
Zone: res.Zone,
261+
ServerID: &res.ID,
262+
})
263+
if err != nil {
264+
return diag.FromErr(err)
265+
}
266+
for _, v := range listPrivateNetworks.ServerPrivateNetworks {
267+
err = privateNetworkAPI.DeleteServerPrivateNetwork(&applesilicon.PrivateNetworkAPIDeleteServerPrivateNetworkRequest{
268+
Zone: zone,
269+
ServerID: v.ServerID,
270+
PrivateNetworkID: v.PrivateNetworkID,
271+
})
272+
if err != nil {
273+
return diag.FromErr(err)
274+
}
275+
}
276+
277+
}
176278
}
177279

178280
_, err = asAPI.UpdateServer(req, scw.WithContext(ctx))
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package applesilicon
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
applesilicon "github.com/scaleway/scaleway-sdk-go/api/applesilicon/v1alpha1"
6+
"github.com/scaleway/scaleway-sdk-go/scw"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality"
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
9+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
10+
)
11+
12+
func expandPrivateNetworks(pn interface{}) map[string]*[]string {
13+
privateNetworks := make(map[string]*[]string)
14+
15+
for _, op := range pn.(*schema.Set).List() {
16+
rawPN := op.(map[string]interface{})
17+
id := locality.ExpandID(rawPN["id"].(string))
18+
19+
ipamIPIDs := &[]string{}
20+
if ipamIPs, ok := rawPN["ipam_ip_ids"]; ok && ipamIPs != nil {
21+
ipamIPsList := ipamIPs.([]interface{})
22+
if len(ipamIPsList) > 0 {
23+
ips := make([]string, len(ipamIPsList))
24+
for i, ip := range ipamIPsList {
25+
ips[i] = locality.ExpandID(ip.(string))
26+
}
27+
ipamIPIDs = &ips
28+
}
29+
}
30+
privateNetworks[id] = ipamIPIDs
31+
}
32+
return privateNetworks
33+
}
34+
35+
func flattenPrivateNetworks(region scw.Region, privateNetworks []*applesilicon.ServerPrivateNetwork) interface{} {
36+
flattenedPrivateNetworks := []map[string]interface{}(nil)
37+
for _, privateNetwork := range privateNetworks {
38+
flattenedPrivateNetworks = append(flattenedPrivateNetworks, map[string]interface{}{
39+
"id": regional.NewIDString(region, privateNetwork.PrivateNetworkID),
40+
"ipam_ip_ids": regional.NewRegionalIDs(region, privateNetwork.IpamIPIDs),
41+
"vlan": types.FlattenUint32Ptr(privateNetwork.Vlan),
42+
"status": privateNetwork.Status,
43+
"created_at": types.FlattenTime(privateNetwork.CreatedAt),
44+
"updated_at": types.FlattenTime(privateNetwork.UpdatedAt),
45+
})
46+
}
47+
return flattenedPrivateNetworks
48+
}

internal/services/applesilicon/waiters.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,19 @@ func waitForAppleSiliconServer(ctx context.Context, api *applesilicon.API, zone
2929

3030
return server, err
3131
}
32+
33+
func waitForAppleSiliconPrivateNetworkServer(ctx context.Context, api *applesilicon.PrivateNetworkAPI, zone scw.Zone, serverID string, timeout time.Duration) (*[]applesilicon.ServerPrivateNetwork, error) {
34+
retryInterval := defaultAppleSiliconServerRetryInterval
35+
if transport.DefaultWaitRetryInterval != nil {
36+
retryInterval = *transport.DefaultWaitRetryInterval
37+
}
38+
39+
privateNetwork, err := api.WaitForServerPrivateNetworks(&applesilicon.WaitForServerRequest{
40+
ServerID: serverID,
41+
Zone: zone,
42+
Timeout: scw.TimeDurationPtr(timeout),
43+
RetryInterval: &retryInterval,
44+
}, scw.WithContext(ctx))
45+
46+
return privateNetwork, err
47+
}

0 commit comments

Comments
 (0)