Skip to content

Commit 1caa5a2

Browse files
authored
Improve public IPs management (#25)
1 parent edd69dd commit 1caa5a2

File tree

8 files changed

+345
-75
lines changed

8 files changed

+345
-75
lines changed

internal/service/scaleway/client/instance.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type InstanceAPI interface {
3333
DeleteServer(req *instance.DeleteServerRequest, opts ...scw.RequestOption) error
3434
ListPlacementGroups(req *instance.ListPlacementGroupsRequest, opts ...scw.RequestOption) (*instance.ListPlacementGroupsResponse, error)
3535
ListSecurityGroups(req *instance.ListSecurityGroupsRequest, opts ...scw.RequestOption) (*instance.ListSecurityGroupsResponse, error)
36+
UpdateServer(req *instance.UpdateServerRequest, opts ...scw.RequestOption) (*instance.UpdateServerResponse, error)
3637
}
3738

3839
type Instance interface {
@@ -44,7 +45,7 @@ type Instance interface {
4445
placementGroupID, securityGroupID *string,
4546
rootVolumeSize scw.Size,
4647
rootVolumeType instance.VolumeVolumeType,
47-
publicIPs, tags []string,
48+
tags []string,
4849
) (*instance.Server, error)
4950
FindImage(ctx context.Context, zone scw.Zone, name string) (*instance.Image, error)
5051
FindIPs(ctx context.Context, zone scw.Zone, tags []string) ([]*instance.IP, error)
@@ -62,6 +63,7 @@ type Instance interface {
6263
DeleteServer(ctx context.Context, zone scw.Zone, serverID string) error
6364
FindPlacementGroup(ctx context.Context, zone scw.Zone, name string) (*instance.PlacementGroup, error)
6465
FindSecurityGroup(ctx context.Context, zone scw.Zone, name string) (*instance.SecurityGroup, error)
66+
UpdateServerPublicIPs(ctx context.Context, zone scw.Zone, id string, publicIPIDs []string) (*instance.Server, error)
6567
}
6668

6769
// FindServer finds an existing Instance server by tags.
@@ -106,7 +108,7 @@ func (c *Client) CreateServer(
106108
placementGroupID, securityGroupID *string,
107109
rootVolumeSize scw.Size,
108110
rootVolumeType instance.VolumeVolumeType,
109-
publicIPs, tags []string,
111+
tags []string,
110112
) (*instance.Server, error) {
111113
if err := c.validateZone(c.instance, zone); err != nil {
112114
return nil, err
@@ -138,10 +140,6 @@ func (c *Client) CreateServer(
138140
Tags: append(tags, createdByTag),
139141
}
140142

141-
if len(publicIPs) > 0 {
142-
req.PublicIPs = &publicIPs
143-
}
144-
145143
// Automatically attach scratch volume if server supports it.
146144
if serverType.ScratchStorageMaxSize != nil && *serverType.ScratchStorageMaxSize > 0 {
147145
req.Volumes["1"] = &instance.VolumeServerTemplate{
@@ -482,3 +480,20 @@ func (c *Client) FindSecurityGroup(ctx context.Context, zone scw.Zone, name stri
482480
return nil, fmt.Errorf("%w: found %d security groups with name %s", ErrTooManyItemsFound, len(securityGroups), name)
483481
}
484482
}
483+
484+
func (c *Client) UpdateServerPublicIPs(ctx context.Context, zone scw.Zone, id string, publicIPIDs []string) (*instance.Server, error) {
485+
if err := c.validateZone(c.instance, zone); err != nil {
486+
return nil, err
487+
}
488+
489+
resp, err := c.instance.UpdateServer(&instance.UpdateServerRequest{
490+
Zone: zone,
491+
ServerID: id,
492+
PublicIPs: &publicIPIDs,
493+
}, scw.WithContext(ctx))
494+
if err != nil {
495+
return nil, newCallError("UpdateServer", err)
496+
}
497+
498+
return resp.Server, nil
499+
}

internal/service/scaleway/client/instance_test.go

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ func TestClient_CreateServer(t *testing.T) {
176176
securityGroupID *string
177177
rootVolumeSize scw.Size
178178
rootVolumeType instance.VolumeVolumeType
179-
publicIPs []string
180179
tags []string
181180
}
182181
tests := []struct {
@@ -203,7 +202,6 @@ func TestClient_CreateServer(t *testing.T) {
203202
securityGroupID: scw.StringPtr(securityGroupID),
204203
rootVolumeSize: rootVolumeSize,
205204
rootVolumeType: instance.VolumeVolumeTypeBSSD,
206-
publicIPs: []string{"42.42.42.42"},
207205
tags: []string{"tag1", "tag2", "tag3"},
208206
},
209207
expect: func(d *mock_client.MockInstanceAPIMockRecorder) {
@@ -227,8 +225,7 @@ func TestClient_CreateServer(t *testing.T) {
227225
Boot: scw.BoolPtr(true),
228226
},
229227
},
230-
Tags: []string{"tag1", "tag2", "tag3", createdByTag},
231-
PublicIPs: &[]string{"42.42.42.42"},
228+
Tags: []string{"tag1", "tag2", "tag3", createdByTag},
232229
}, gomock.Any()).Return(&instance.CreateServerResponse{
233230
Server: &instance.Server{
234231
Name: "server",
@@ -316,7 +313,7 @@ func TestClient_CreateServer(t *testing.T) {
316313
region: tt.fields.region,
317314
instance: instanceMock,
318315
}
319-
got, err := c.CreateServer(tt.args.ctx, tt.args.zone, tt.args.name, tt.args.commercialType, tt.args.imageID, tt.args.placementGroupID, tt.args.securityGroupID, tt.args.rootVolumeSize, tt.args.rootVolumeType, tt.args.publicIPs, tt.args.tags)
316+
got, err := c.CreateServer(tt.args.ctx, tt.args.zone, tt.args.name, tt.args.commercialType, tt.args.imageID, tt.args.placementGroupID, tt.args.securityGroupID, tt.args.rootVolumeSize, tt.args.rootVolumeType, tt.args.tags)
320317
if (err != nil) != tt.wantErr {
321318
t.Errorf("Client.CreateServer() error = %v, wantErr %v", err, tt.wantErr)
322319
return
@@ -1731,3 +1728,82 @@ func TestClient_FindSecurityGroup(t *testing.T) {
17311728
})
17321729
}
17331730
}
1731+
1732+
func TestClient_UpdateServerPublicIPs(t *testing.T) {
1733+
t.Parallel()
1734+
type fields struct {
1735+
projectID string
1736+
region scw.Region
1737+
}
1738+
type args struct {
1739+
ctx context.Context
1740+
zone scw.Zone
1741+
id string
1742+
publicIPIDs []string
1743+
}
1744+
tests := []struct {
1745+
name string
1746+
fields fields
1747+
args args
1748+
want *instance.Server
1749+
wantErr bool
1750+
expect func(d *mock_client.MockInstanceAPIMockRecorder)
1751+
}{
1752+
{
1753+
name: "update public IPs",
1754+
fields: fields{
1755+
projectID: projectID,
1756+
region: scw.RegionFrPar,
1757+
},
1758+
args: args{
1759+
ctx: context.TODO(),
1760+
zone: scw.ZoneFrPar1,
1761+
id: serverID,
1762+
publicIPIDs: []string{ipID},
1763+
},
1764+
want: &instance.Server{
1765+
ID: serverID,
1766+
},
1767+
expect: func(d *mock_client.MockInstanceAPIMockRecorder) {
1768+
d.UpdateServer(&instance.UpdateServerRequest{
1769+
Zone: scw.ZoneFrPar1,
1770+
ServerID: serverID,
1771+
PublicIPs: &[]string{ipID},
1772+
}, gomock.Any()).Return(&instance.UpdateServerResponse{
1773+
Server: &instance.Server{
1774+
ID: serverID,
1775+
},
1776+
}, nil)
1777+
},
1778+
},
1779+
}
1780+
for _, tt := range tests {
1781+
t.Run(tt.name, func(t *testing.T) {
1782+
t.Parallel()
1783+
1784+
mockCtrl := gomock.NewController(t)
1785+
defer mockCtrl.Finish()
1786+
1787+
instanceMock := mock_client.NewMockInstanceAPI(mockCtrl)
1788+
1789+
// Every API call must be preceded by a zone check.
1790+
instanceMock.EXPECT().Zones().Return(tt.fields.region.GetZones())
1791+
1792+
tt.expect(instanceMock.EXPECT())
1793+
1794+
c := &Client{
1795+
projectID: tt.fields.projectID,
1796+
region: tt.fields.region,
1797+
instance: instanceMock,
1798+
}
1799+
got, err := c.UpdateServerPublicIPs(tt.args.ctx, tt.args.zone, tt.args.id, tt.args.publicIPIDs)
1800+
if (err != nil) != tt.wantErr {
1801+
t.Errorf("Client.UpdateServerPublicIPs() error = %v, wantErr %v", err, tt.wantErr)
1802+
return
1803+
}
1804+
if !reflect.DeepEqual(got, tt.want) {
1805+
t.Errorf("Client.UpdateServerPublicIPs() = %v, want %v", got, tt.want)
1806+
}
1807+
})
1808+
}
1809+
}

internal/service/scaleway/client/mock_client/client_mock.go

Lines changed: 45 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)