Skip to content

Commit 245b2f0

Browse files
Added support for networking/ and vpcs/ endpoint changs for VPC Linodes Enhanced Interfaces (#727)
* Added support for networking/firewalls related changes * Added support for Networking IPs and VPC changes * Addressed PR comments
1 parent 6fd4b61 commit 245b2f0

18 files changed

Lines changed: 349 additions & 102 deletions

firewall_devices.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type FirewallDeviceType string
1515
const (
1616
FirewallDeviceLinode FirewallDeviceType = "linode"
1717
FirewallDeviceNodeBalancer FirewallDeviceType = "nodebalancer"
18+
FirewallDeviceInterface FirewallDeviceType = "interface"
1819
)
1920

2021
// FirewallDevice represents a device governed by a Firewall

firewalls.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type Firewall struct {
3333
type DevicesCreationOptions struct {
3434
Linodes []int `json:"linodes,omitempty"`
3535
NodeBalancers []int `json:"nodebalancers,omitempty"`
36+
Interfaces []int `json:"interfaces,omitempty"`
3637
}
3738

3839
// FirewallCreateOptions fields are those accepted by CreateFirewall
@@ -50,6 +51,31 @@ type FirewallUpdateOptions struct {
5051
Tags *[]string `json:"tags,omitempty"`
5152
}
5253

54+
// FirewallSettings represents the default firewalls for Linodes,
55+
// Linode VPC and public interfaces, and NodeBalancers.
56+
type FirewallSettings struct {
57+
DefaultFirewallIDs DefaultFirewallIDs `json:"default_firewall_ids"`
58+
}
59+
60+
type DefaultFirewallIDs struct {
61+
Linode int `json:"linode"`
62+
NodeBalancer int `json:"nodebalancer"`
63+
PublicInterface int `json:"public_interface"`
64+
VPCInterface int `json:"vpc_interface"`
65+
}
66+
67+
// FirewallSettingsUpdateOptions is an options struct used when Updating FirewallSettings
68+
type FirewallSettingsUpdateOptions struct {
69+
DefaultFirewallIDs DefaultFirewallIDsOptions `json:"default_firewall_ids"`
70+
}
71+
72+
type DefaultFirewallIDsOptions struct {
73+
Linode *int `json:"linode,omitempty"`
74+
NodeBalancer *int `json:"nodebalancer,omitempty"`
75+
PublicInterface *int `json:"public_interface,omitempty"`
76+
VPCInterface *int `json:"vpc_interface,omitempty"`
77+
}
78+
5379
// GetUpdateOptions converts a Firewall to FirewallUpdateOptions for use in Client.UpdateFirewall.
5480
func (f *Firewall) GetUpdateOptions() FirewallUpdateOptions {
5581
return FirewallUpdateOptions{
@@ -107,3 +133,13 @@ func (c *Client) DeleteFirewall(ctx context.Context, firewallID int) error {
107133
e := formatAPIPath("networking/firewalls/%d", firewallID)
108134
return doDELETERequest(ctx, c, e)
109135
}
136+
137+
// GetFirewallSettings returns default firewalls for Linodes, Linode VPC and public interfaces, and NodeBalancers.
138+
func (c *Client) GetFirewallSettings(ctx context.Context) (*FirewallSettings, error) {
139+
return doGETRequest[FirewallSettings](ctx, c, "networking/firewalls/settings")
140+
}
141+
142+
// UpdateFirewallSettings updates the default firewalls for Linodes, Linode VPC and public interfaces, and NodeBalancers.
143+
func (c *Client) UpdateFirewallSettings(ctx context.Context, opts FirewallSettingsUpdateOptions) (*FirewallSettings, error) {
144+
return doPUTRequest[FirewallSettings](ctx, c, "networking/firewalls/settings", opts)
145+
}

go.work.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5
5656
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
5757
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
5858
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
59+
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
5960
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
6061
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
6162
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
@@ -77,17 +78,16 @@ golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
7778
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
7879
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
7980
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
81+
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
8082
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
8183
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
8284
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
83-
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
8485
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY=
8586
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
8687
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk=
8788
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
8889
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
8990
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
90-
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
9191
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
9292
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
9393
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=

instance_ips.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,18 @@ type InstanceIPv4Response struct {
2121

2222
// InstanceIP represents an Instance IP with additional DNS and networking details
2323
type InstanceIP struct {
24-
Address string `json:"address"`
25-
Gateway string `json:"gateway"`
26-
SubnetMask string `json:"subnet_mask"`
27-
Prefix int `json:"prefix"`
28-
Type InstanceIPType `json:"type"`
29-
Public bool `json:"public"`
30-
RDNS string `json:"rdns"`
31-
LinodeID int `json:"linode_id"`
32-
Region string `json:"region"`
33-
VPCNAT1To1 *InstanceIPNAT1To1 `json:"vpc_nat_1_1"`
34-
Reserved bool `json:"reserved"`
24+
Address string `json:"address"`
25+
Gateway string `json:"gateway"`
26+
SubnetMask string `json:"subnet_mask"`
27+
Prefix int `json:"prefix"`
28+
Type InstanceIPType `json:"type"`
29+
Public bool `json:"public"`
30+
RDNS string `json:"rdns"`
31+
LinodeID int `json:"linode_id"`
32+
InterfaceID *int `json:"interface_id"`
33+
Region string `json:"region"`
34+
VPCNAT1To1 *InstanceIPNAT1To1 `json:"vpc_nat_1_1"`
35+
Reserved bool `json:"reserved"`
3536
}
3637

3738
// VPCIP represents a private IP address in a VPC subnet with additional networking details

regions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
CapabilityEdgePlans string = "Edge Plans"
2323
CapabilityGPU string = "GPU Linodes"
2424
CapabilityKubernetesEnterprise string = "Kubernetes Enterprise"
25+
CapabilityLinodeInterfaces string = "Linode Interfaces"
2526
CapabilityLKE string = "Kubernetes"
2627
CapabilityLKEControlPlaneACL string = "LKE Network Access Control List (IP ACL)"
2728
CapabilityLinodes string = "Linodes"

test/unit/firewalls_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ func TestFirewall_Create(t *testing.T) {
9898
},
9999
},
100100
Tags: []string{"example tag", "another example"},
101+
Devices: linodego.DevicesCreationOptions{
102+
Interfaces: []int{1, 2, 3},
103+
},
101104
}
102105

103106
base.MockPost(formatMockAPIPath("networking/firewalls"), fixtureData)
@@ -250,3 +253,54 @@ func TestFirewall_Delete(t *testing.T) {
250253
t.Fatal(err)
251254
}
252255
}
256+
257+
func TestDefaultFirewall_Get(t *testing.T) {
258+
fixtureData, err := fixtures.GetFixture("default_firewalls_get")
259+
assert.NoError(t, err)
260+
261+
var base ClientBaseCase
262+
base.SetUp(t)
263+
defer base.TearDown(t)
264+
265+
base.MockGet(formatMockAPIPath("networking/firewalls/settings"), fixtureData)
266+
267+
defaultFirewalls, err := base.Client.GetFirewallSettings(context.Background())
268+
269+
assert.NoError(t, err)
270+
assert.NotNil(t, defaultFirewalls)
271+
272+
assert.Equal(t, 101, defaultFirewalls.DefaultFirewallIDs.NodeBalancer)
273+
assert.Equal(t, 100, defaultFirewalls.DefaultFirewallIDs.Linode)
274+
assert.Equal(t, 200, defaultFirewalls.DefaultFirewallIDs.PublicInterface)
275+
assert.Equal(t, 200, defaultFirewalls.DefaultFirewallIDs.VPCInterface)
276+
}
277+
278+
func TestDefaultFirewall_Update(t *testing.T) {
279+
fixtureData, err := fixtures.GetFixture("default_firewalls_update")
280+
assert.NoError(t, err)
281+
282+
var base ClientBaseCase
283+
base.SetUp(t)
284+
defer base.TearDown(t)
285+
286+
base.MockPut(formatMockAPIPath("networking/firewalls/settings"), fixtureData)
287+
288+
requestData := linodego.FirewallSettingsUpdateOptions{
289+
DefaultFirewallIDs: linodego.DefaultFirewallIDsOptions{
290+
Linode: linodego.Pointer(1),
291+
NodeBalancer: linodego.Pointer(1),
292+
VPCInterface: linodego.Pointer(1),
293+
PublicInterface: linodego.Pointer(1),
294+
},
295+
}
296+
297+
defaultFirewalls, err := base.Client.UpdateFirewallSettings(context.Background(), requestData)
298+
299+
assert.NoError(t, err)
300+
assert.NotNil(t, defaultFirewalls)
301+
302+
assert.Equal(t, 1, defaultFirewalls.DefaultFirewallIDs.NodeBalancer)
303+
assert.Equal(t, 1, defaultFirewalls.DefaultFirewallIDs.Linode)
304+
assert.Equal(t, 1, defaultFirewalls.DefaultFirewallIDs.PublicInterface)
305+
assert.Equal(t, 1, defaultFirewalls.DefaultFirewallIDs.VPCInterface)
306+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"default_firewall_ids": {
3+
"linode": 100,
4+
"nodebalancer": 101,
5+
"public_interface": 200,
6+
"vpc_interface": 200
7+
}
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"default_firewall_ids": {
3+
"linode": 1,
4+
"nodebalancer": 1,
5+
"public_interface": 1,
6+
"vpc_interface": 1
7+
}
8+
}
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
{
2-
"address": "192.168.1.1",
3-
"linode_id": 12345,
4-
"reserved": false
5-
}
2+
"address": "97.107.143.141",
3+
"gateway": "97.107.143.1",
4+
"interface_id": 456,
5+
"linode_id": 123,
6+
"prefix": 24,
7+
"public": true,
8+
"rdns": "test.example.org",
9+
"region": "us-east",
10+
"subnet_mask": "255.255.255.0",
11+
"type": "ipv4",
12+
"vpc_nat_1_1": {
13+
"address": "192.168.0.42",
14+
"subnet_id": 101,
15+
"vpc_id": 111
16+
}
17+
}
Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
{
22
"data": [
33
{
4-
"address": "192.168.1.1",
5-
"linode_id": 12345,
6-
"reserved": false
7-
},
8-
{
9-
"address": "192.168.1.2",
10-
"linode_id": 67890,
11-
"reserved": true
4+
"address": "197.1O7.143.141",
5+
"gateway": "197.1O7.143.1",
6+
"interface_id": 456,
7+
"linode_id": 123,
8+
"prefix": 24,
9+
"public": true,
10+
"rdns": "test.example.org",
11+
"region": "us-east",
12+
"subnet_mask": "192.0.2.139",
13+
"type": "ipv4",
14+
"vpc_nat_1_1": {
15+
"address": "192.0.2.1",
16+
"subnet_id": 101,
17+
"vpc_id": 111
18+
}
1219
}
1320
],
21+
"page": 1,
1422
"pages": 1,
15-
"results": 2
16-
}
23+
"results": 1
24+
}

0 commit comments

Comments
 (0)