Skip to content

Commit 023554c

Browse files
komer3Rahul Sharmalgarber-akamaizliang-akamai
authored
Nodebalancer VPC support (#678)
* Adding the funcs for the List VPC and Get VPC for Nodebalancers endpoints * Adding test cases - they don't work until we update some nodebalancer funcs to allow creation of nb with vpc options * IPv6 can sometime be empty so adding omiempty here * add vpcs config during nodebalancer create * update node config as well * add nb vpc test * Adding records for fixtures * add generated fixtures * fix cleanup failures * Update the fixture for nb vpc list and get * fix formatting * Update nodebalancer_config_vpc.go Co-authored-by: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> * Fix naming * Adding disclaimer for letting users know this might not be available to everyone * Remove use of pointers with VPC options --------- Co-authored-by: Rahul Sharma <rahsharm@akamai.com> Co-authored-by: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Co-authored-by: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com>
1 parent 9f33446 commit 023554c

8 files changed

+1990
-4
lines changed

nodebalancer.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ type NodeBalancerTransfer struct {
4444
In *float64 `json:"in"`
4545
}
4646

47+
type NodeBalancerVPCOptions struct {
48+
IPv4Range string `json:"ipv4_range"`
49+
IPv6Range string `json:"ipv6_range,omitempty"`
50+
SubnetID int `json:"subnet_id"`
51+
}
52+
4753
// NodeBalancerCreateOptions are the options permitted for CreateNodeBalancer
4854
type NodeBalancerCreateOptions struct {
4955
Label *string `json:"label,omitempty"`
@@ -52,6 +58,7 @@ type NodeBalancerCreateOptions struct {
5258
Configs []*NodeBalancerConfigCreateOptions `json:"configs,omitempty"`
5359
Tags []string `json:"tags"`
5460
FirewallID int `json:"firewall_id,omitempty"`
61+
VPCs []NodeBalancerVPCOptions `json:"vpcs,omitempty"`
5562
}
5663

5764
// NodeBalancerUpdateOptions are the options permitted for UpdateNodeBalancer

nodebalancer_config_nodes.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ var (
3535

3636
// NodeBalancerNodeCreateOptions fields are those accepted by CreateNodeBalancerNode
3737
type NodeBalancerNodeCreateOptions struct {
38-
Address string `json:"address"`
39-
Label string `json:"label"`
40-
Weight int `json:"weight,omitempty"`
41-
Mode NodeMode `json:"mode,omitempty"`
38+
Address string `json:"address"`
39+
Label string `json:"label"`
40+
Weight int `json:"weight,omitempty"`
41+
Mode NodeMode `json:"mode,omitempty"`
42+
SubnetID int `json:"subnet_id,omitempty"`
4243
}
4344

4445
// NodeBalancerNodeUpdateOptions fields are those accepted by UpdateNodeBalancerNode

nodebalancer_config_vpc.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package linodego
2+
3+
import (
4+
"context"
5+
)
6+
7+
// NodeBalancerVPCConfig objects represent a VPC config for a NodeBalancer
8+
// s
9+
// NOTE: NodeBalancer VPC support may not currently be available to all users.
10+
type NodeBalancerVPCConfig struct {
11+
ID int `json:"id"`
12+
IPv4Range string `json:"ipv4_range"`
13+
IPv6Range string `json:"ipv6_range,omitempty"`
14+
NodeBalancerID int `json:"nodebalancer_id"`
15+
SubnetID int `json:"subnet_id"`
16+
VPCID int `json:"vpc_id"`
17+
}
18+
19+
// ListNodeBalancerVPCConfigs lists NodeBalancer VPC configs
20+
func (c *Client) ListNodeBalancerVPCConfigs(ctx context.Context, nodebalancerID int, opts *ListOptions) ([]NodeBalancerVPCConfig, error) {
21+
return getPaginatedResults[NodeBalancerVPCConfig](ctx, c, formatAPIPath("nodebalancers/%d/vpcs", nodebalancerID), opts)
22+
}
23+
24+
// GetNodeBalancerVPCConfig gets the NodeBalancer VPC config with the specified id
25+
func (c *Client) GetNodeBalancerVPCConfig(ctx context.Context, nodebalancerID int, vpcID int) (*NodeBalancerVPCConfig, error) {
26+
e := formatAPIPath("nodebalancers/%d/vpcs/%d", nodebalancerID, vpcID)
27+
return doGETRequest[NodeBalancerVPCConfig](ctx, c, e)
28+
}

test/integration/fixtures/TestNodeBalancerVpcConfig_Get.yaml

Lines changed: 682 additions & 0 deletions
Large diffs are not rendered by default.

test/integration/fixtures/TestNodeBalancerVpcConfig_List.yaml

Lines changed: 619 additions & 0 deletions
Large diffs are not rendered by default.

test/integration/fixtures/TestNodeBalancer_With_VPC_Create.yaml

Lines changed: 546 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestNodeBalancerVPCConfig_List(t *testing.T) {
11+
client, nodebalancer, teardown, err := setupNodeBalancerWithVPC(t, "fixtures/TestNodeBalancerVpcConfig_List")
12+
if err != nil {
13+
t.Errorf("Error setting up nodebalancer: %s", err)
14+
}
15+
defer teardown()
16+
17+
configs, err := client.ListNodeBalancerVPCConfigs(context.Background(), nodebalancer.ID, nil)
18+
if err != nil {
19+
t.Errorf("Error listing nodebalancer VPC configs: %s", err)
20+
}
21+
22+
// We expect the list to be not empty and have at least one VPC config
23+
require.NotEmpty(t, configs)
24+
require.Len(t, configs, 1)
25+
}
26+
27+
func TestNodeBalancerVPCConfig_Get(t *testing.T) {
28+
client, nodebalancer, teardown, err := setupNodeBalancerWithVPC(t, "fixtures/TestNodeBalancerVpcConfig_Get")
29+
if err != nil {
30+
t.Errorf("Error setting up nodebalancer: %s", err)
31+
}
32+
defer teardown()
33+
34+
// Get the VPC config list for the nodebalancer (should only have one)
35+
configs, err := client.ListNodeBalancerVPCConfigs(context.Background(), nodebalancer.ID, nil)
36+
if err != nil {
37+
t.Errorf("Error listing nodebalancer VPC configs: %s", err)
38+
}
39+
require.NotEmpty(t, configs)
40+
require.Len(t, configs, 1)
41+
42+
// Get the VPC config by ID
43+
config, err := client.GetNodeBalancerVPCConfig(context.Background(), nodebalancer.ID, configs[0].ID)
44+
if err != nil {
45+
t.Errorf("Error getting nodebalancer VPC config: %s", err)
46+
}
47+
require.NotNil(t, config)
48+
require.Equal(t, configs[0].ID, config.ID)
49+
}

test/integration/nodebalancers_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@ func TestNodeBalancer_Create_create_smoke(t *testing.T) {
3030
assertDateSet(t, nodebalancer.Updated)
3131
}
3232

33+
func TestNodeBalancer_Create_with_vpc(t *testing.T) {
34+
_, nodebalancer, teardown, err := setupNodeBalancerWithVPC(t, "fixtures/TestNodeBalancer_With_VPC_Create")
35+
defer teardown()
36+
37+
if err != nil {
38+
t.Errorf("Error creating nodebalancer: %v", err)
39+
}
40+
41+
// when comparing fixtures to random value Label will differ, compare the known suffix
42+
if !strings.Contains(*nodebalancer.Label, label) {
43+
t.Errorf("nodebalancer returned does not match nodebalancer create request")
44+
}
45+
46+
assertDateSet(t, nodebalancer.Created)
47+
assertDateSet(t, nodebalancer.Updated)
48+
}
49+
3350
func TestNodeBalancer_Update(t *testing.T) {
3451
client, nodebalancer, teardown, err := setupNodeBalancer(t, "fixtures/TestNodeBalancer_Update")
3552
defer teardown()
@@ -104,3 +121,40 @@ func setupNodeBalancer(t *testing.T, fixturesYaml string) (*linodego.Client, *li
104121
}
105122
return client, nodebalancer, teardown, err
106123
}
124+
125+
func setupNodeBalancerWithVPC(t *testing.T, fixturesYaml string) (*linodego.Client, *linodego.NodeBalancer, func(), error) {
126+
t.Helper()
127+
var fixtureTeardown func()
128+
client, fixtureTeardown := createTestClient(t, fixturesYaml)
129+
vpc, subnet, vpcTeardown, err := createVPCWithSubnet(t, client)
130+
if err != nil {
131+
t.Errorf("Error creating vpc, got error %v", err)
132+
}
133+
createOpts := linodego.NodeBalancerCreateOptions{
134+
Label: &label,
135+
Region: vpc.Region,
136+
ClientConnThrottle: &clientConnThrottle,
137+
FirewallID: GetFirewallID(),
138+
VPCs: []linodego.NodeBalancerVPCOptions{
139+
{
140+
IPv4Range: "192.168.0.64/30",
141+
IPv6Range: "",
142+
SubnetID: subnet.ID,
143+
},
144+
},
145+
}
146+
147+
nodebalancer, err := client.CreateNodeBalancer(context.Background(), createOpts)
148+
if err != nil {
149+
t.Fatalf("Error listing nodebalancers, expected struct, got error %v", err)
150+
}
151+
152+
teardown := func() {
153+
if err := client.DeleteNodeBalancer(context.Background(), nodebalancer.ID); err != nil {
154+
t.Errorf("Expected to delete a nodebalancer, but got %v", err)
155+
}
156+
vpcTeardown()
157+
fixtureTeardown()
158+
}
159+
return client, nodebalancer, teardown, err
160+
}

0 commit comments

Comments
 (0)