Skip to content

Commit dbfb8e6

Browse files
authored
feat: VPC NodeBalancer backends behind feature flag (#803)
API: add spec.network.enableVPCBackends (default false, immutable). When true and VPCRef/VPCID is set, create the NodeBalancer in the target VPC and prefer VPC backend IPs. NodeBalancerBackendIPv4Range remains optional and is honored when provided. Services: introduce ShouldUseVPC(scope) and DetermineAPIServerLBPort(scope); EnsureNodeBalancer uses VPC SubnetID and optional IPv4Range; node registration prefers VPC internal IPs when enabled, otherwise falls back to Linode private IPs. Controller: refactor getIPPortCombo to select VPC IPs first, factor helpers findFirstVPCInternalIP/findFirstPrivateInternalIP and buildPortCombosForIP; reuse DetermineAPIServerLBPort for DNS endpoint. CRDs+Docs: extend LinodeCluster CRDs with enableVPCBackends (default false, immutable); update docs reference for the new field. Tests: update unit tests to set EnableVPCBackends=true in VPC scenarios and to use new helpers; keep behavior unchanged when flag is false.
1 parent 4e6e873 commit dbfb8e6

10 files changed

+124
-61
lines changed

api/v1alpha2/linodecluster_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,16 @@ type NetworkSpec struct {
190190
// example: 10.10.10.0/30
191191
// +optional
192192
NodeBalancerBackendIPv4Range string `json:"nodeBalancerBackendIPv4Range,omitempty"`
193+
194+
// EnableVPCBackends toggles VPC-scoped NodeBalancer and VPC backend IP usage.
195+
// If set to false (default), the NodeBalancer will not be created in a VPC and
196+
// backends will use Linode private IPs. If true, the NodeBalancer will be
197+
// created in the configured VPC (when VPCRef or VPCID is set) and backends
198+
// will use VPC IPs.
199+
// +kubebuilder:default=false
200+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
201+
// +optional
202+
EnableVPCBackends bool `json:"enableVPCBackends,omitempty"`
193203
}
194204

195205
type LinodeNBPortConfig struct {

cloud/services/loadbalancers.go

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ const (
2222
DefaultKonnectivityLBPort = 8132
2323
)
2424

25+
// DetermineAPIServerLBPort returns the configured API server load balancer port,
26+
// or the provider default when not explicitly set.
27+
func DetermineAPIServerLBPort(clusterScope *scope.ClusterScope) int {
28+
if clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort != 0 {
29+
return clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort
30+
}
31+
return DefaultApiserverLBPort
32+
}
33+
34+
// ShouldUseVPC decides whether VPC IPs/backends should be preferred and a VPC-scoped
35+
// NodeBalancer should be created. It requires both the feature flag and a VPC reference/ID.
36+
func ShouldUseVPC(clusterScope *scope.ClusterScope) bool {
37+
return clusterScope.LinodeCluster.Spec.Network.EnableVPCBackends && (clusterScope.LinodeCluster.Spec.VPCRef != nil || clusterScope.LinodeCluster.Spec.VPCID != nil)
38+
}
39+
2540
// FindSubnet selects a subnet from the provided subnets based on the subnet name
2641
// It handles both direct VPC subnets and VPCRef subnets
2742
// If subnet name is provided, it looks for a matching subnet; otherwise, it uses the first subnet
@@ -125,19 +140,18 @@ func EnsureNodeBalancer(ctx context.Context, clusterScope *scope.ClusterScope, l
125140
Tags: []string{string(clusterScope.LinodeCluster.UID)},
126141
}
127142

128-
// if NodeBalancerBackendIPv4Range is set, create the NodeBalancer in the specified VPC
129-
if clusterScope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range != "" && (clusterScope.LinodeCluster.Spec.VPCRef != nil || clusterScope.LinodeCluster.Spec.VPCID != nil) {
130-
logger.Info("Creating NodeBalancer in VPC", "NodeBalancerBackendIPv4Range", clusterScope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range)
143+
// if enableVPCBackends is true and vpcRef or vpcID is set, create the NodeBalancer in the specified VPC
144+
if ShouldUseVPC(clusterScope) {
145+
logger.Info("Creating NodeBalancer in VPC")
131146
subnetID, err := getSubnetID(ctx, clusterScope, logger)
132147
if err != nil {
133148
logger.Error(err, "Failed to fetch Linode Subnet ID")
134149
return nil, err
135150
}
136-
createConfig.VPCs = []linodego.NodeBalancerVPCOptions{
137-
{
138-
IPv4Range: clusterScope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range,
139-
SubnetID: subnetID,
140-
},
151+
152+
createConfig.VPCs = []linodego.NodeBalancerVPCOptions{{SubnetID: subnetID}}
153+
if clusterScope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range != "" {
154+
createConfig.VPCs[0].IPv4Range = clusterScope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range
141155
}
142156
}
143157

@@ -264,10 +278,7 @@ func EnsureNodeBalancerConfigs(
264278
nbConfigs := []*linodego.NodeBalancerConfig{}
265279
var apiserverLinodeNBConfig *linodego.NodeBalancerConfig
266280
var err error
267-
apiLBPort := DefaultApiserverLBPort
268-
if clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort != 0 {
269-
apiLBPort = clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort
270-
}
281+
apiLBPort := DetermineAPIServerLBPort(clusterScope)
271282

272283
if clusterScope.LinodeCluster.Spec.Network.ApiserverNodeBalancerConfigID != nil {
273284
apiserverLinodeNBConfig, err = clusterScope.LinodeClient.GetNodeBalancerConfig(
@@ -325,10 +336,7 @@ func EnsureNodeBalancerConfigs(
325336
}
326337

327338
func processAndCreateNodeBalancerNodes(ctx context.Context, ipAddress string, clusterScope *scope.ClusterScope, nodeBalancerNodes []linodego.NodeBalancerNode, subnetID int) error {
328-
apiserverLBPort := DefaultApiserverLBPort
329-
if clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort != 0 {
330-
apiserverLBPort = clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort
331-
}
339+
apiserverLBPort := DetermineAPIServerLBPort(clusterScope)
332340

333341
// Set the port number and NB config ID for standard ports
334342
portsToBeAdded := make([]map[string]int, 0)
@@ -382,12 +390,8 @@ func AddNodesToNB(ctx context.Context, logger logr.Logger, clusterScope *scope.C
382390
return errors.New("nil NodeBalancer Config ID")
383391
}
384392

385-
// if NodeBalancerBackendIPv4Range is set, we want to prioritize finding the VPC IP address
386-
// otherwise, we will use the private IP address
387393
subnetID := 0
388-
useVPCIps := clusterScope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range != "" && clusterScope.LinodeCluster.Spec.VPCRef != nil
389-
if useVPCIps {
390-
// Get subnetID
394+
if ShouldUseVPC(clusterScope) {
391395
subnetID, err := getSubnetID(ctx, clusterScope, logger)
392396
if err != nil {
393397
logger.Error(err, "Failed to fetch Linode Subnet ID")

cloud/services/loadbalancers_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ func TestEnsureNodeBalancer(t *testing.T) {
276276
Namespace: "default",
277277
},
278278
Network: infrav1alpha2.NetworkSpec{
279+
EnableVPCBackends: true,
279280
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
280281
},
281282
},
@@ -339,6 +340,7 @@ func TestEnsureNodeBalancer(t *testing.T) {
339340
Region: "us-east",
340341
VPCID: ptr.To(456),
341342
Network: infrav1alpha2.NetworkSpec{
343+
EnableVPCBackends: true,
342344
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
343345
},
344346
},
@@ -393,6 +395,7 @@ func TestEnsureNodeBalancer(t *testing.T) {
393395
Region: "us-east",
394396
VPCID: ptr.To(789),
395397
Network: infrav1alpha2.NetworkSpec{
398+
EnableVPCBackends: true,
396399
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
397400
},
398401
},
@@ -420,6 +423,7 @@ func TestEnsureNodeBalancer(t *testing.T) {
420423
Namespace: "default",
421424
},
422425
Network: infrav1alpha2.NetworkSpec{
426+
EnableVPCBackends: true,
423427
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
424428
},
425429
},
@@ -1713,6 +1717,7 @@ func TestAddNodeToNBFullWorkflow(t *testing.T) {
17131717
Namespace: "default",
17141718
},
17151719
Network: infrav1alpha2.NetworkSpec{
1720+
EnableVPCBackends: true,
17161721
NodeBalancerID: ptr.To(1234),
17171722
ApiserverNodeBalancerConfigID: ptr.To(5678),
17181723
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
@@ -1786,6 +1791,7 @@ func TestAddNodeToNBFullWorkflow(t *testing.T) {
17861791
Namespace: "default",
17871792
},
17881793
Network: infrav1alpha2.NetworkSpec{
1794+
EnableVPCBackends: true,
17891795
NodeBalancerID: ptr.To(1234),
17901796
ApiserverNodeBalancerConfigID: ptr.To(5678),
17911797
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
@@ -1844,6 +1850,7 @@ func TestAddNodeToNBFullWorkflow(t *testing.T) {
18441850
Namespace: "default",
18451851
},
18461852
Network: infrav1alpha2.NetworkSpec{
1853+
EnableVPCBackends: true,
18471854
NodeBalancerID: ptr.To(1234),
18481855
ApiserverNodeBalancerConfigID: ptr.To(5678),
18491856
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
@@ -2564,6 +2571,7 @@ func TestAddNodeToNBWithVPC(t *testing.T) {
25642571
},
25652572
Spec: infrav1alpha2.LinodeClusterSpec{
25662573
Network: infrav1alpha2.NetworkSpec{
2574+
EnableVPCBackends: true,
25672575
ApiserverNodeBalancerConfigID: ptr.To(222),
25682576
NodeBalancerID: ptr.To(111),
25692577
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
@@ -2635,6 +2643,7 @@ func TestAddNodeToNBWithVPC(t *testing.T) {
26352643
},
26362644
Spec: infrav1alpha2.LinodeClusterSpec{
26372645
Network: infrav1alpha2.NetworkSpec{
2646+
EnableVPCBackends: true,
26382647
ApiserverNodeBalancerConfigID: ptr.To(222),
26392648
NodeBalancerID: ptr.To(111),
26402649
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
@@ -2710,6 +2719,7 @@ func TestAddNodeToNBWithVPC(t *testing.T) {
27102719
},
27112720
Spec: infrav1alpha2.LinodeClusterSpec{
27122721
Network: infrav1alpha2.NetworkSpec{
2722+
EnableVPCBackends: true,
27132723
ApiserverNodeBalancerConfigID: ptr.To(222),
27142724
NodeBalancerID: ptr.To(111),
27152725
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
@@ -2819,6 +2829,7 @@ func TestAddNodeToNBWithVPC(t *testing.T) {
28192829
},
28202830
Spec: infrav1alpha2.LinodeClusterSpec{
28212831
Network: infrav1alpha2.NetworkSpec{
2832+
EnableVPCBackends: true,
28222833
ApiserverNodeBalancerConfigID: ptr.To(222),
28232834
NodeBalancerID: ptr.To(111),
28242835
NodeBalancerBackendIPv4Range: "10.0.0.0/24",

config/crd/bases/infrastructure.cluster.x-k8s.io_linodeclusters.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,18 @@ spec:
155155
Ignored if the LoadBalancerType is set to anything other than dns
156156
If not set, CAPL will create a unique identifier for you
157157
type: string
158+
enableVPCBackends:
159+
default: false
160+
description: |-
161+
EnableVPCBackends toggles VPC-scoped NodeBalancer and VPC backend IP usage.
162+
If set to false (default), the NodeBalancer will not be created in a VPC and
163+
backends will use Linode private IPs. If true, the NodeBalancer will be
164+
created in the configured VPC (when VPCRef or VPCID is set) and backends
165+
will use VPC IPs.
166+
type: boolean
167+
x-kubernetes-validations:
168+
- message: Value is immutable
169+
rule: self == oldSelf
158170
loadBalancerType:
159171
default: NodeBalancer
160172
description: LoadBalancerType is the type of load balancer to

config/crd/bases/infrastructure.cluster.x-k8s.io_linodeclustertemplates.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ spec:
151151
Ignored if the LoadBalancerType is set to anything other than dns
152152
If not set, CAPL will create a unique identifier for you
153153
type: string
154+
enableVPCBackends:
155+
default: false
156+
description: |-
157+
EnableVPCBackends toggles VPC-scoped NodeBalancer and VPC backend IP usage.
158+
If set to false (default), the NodeBalancer will not be created in a VPC and
159+
backends will use Linode private IPs. If true, the NodeBalancer will be
160+
created in the configured VPC (when VPCRef or VPCID is set) and backends
161+
will use VPC IPs.
162+
type: boolean
163+
x-kubernetes-validations:
164+
- message: Value is immutable
165+
rule: self == oldSelf
154166
loadBalancerType:
155167
default: NodeBalancer
156168
description: LoadBalancerType is the type of load balancer

docs/src/reference/out.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,7 @@ _Appears in:_
11711171
| `subnetName` _string_ | subnetName is the name/label of the VPC subnet to be used by the cluster | | |
11721172
| `useVlan` _boolean_ | UseVlan provisions a cluster that uses VLANs instead of VPCs. IPAM is managed internally. | | |
11731173
| `nodeBalancerBackendIPv4Range` _string_ | NodeBalancerBackendIPv4Range is the subnet range we want to provide for creating nodebalancer in VPC.<br />example: 10.10.10.0/30 | | |
1174+
| `enableVPCBackends` _boolean_ | EnableVPCBackends toggles VPC-scoped NodeBalancer and VPC backend IP usage.<br />If set to false (default), the NodeBalancer will not be created in a VPC and<br />backends will use Linode private IPs. If true, the NodeBalancer will be<br />created in the configured VPC (when VPCRef or VPCID is set) and backends<br />will use VPC IPs. | false | |
11741175

11751176

11761177
#### ObjectStorageACL

hack/generate-flavors.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ SUPPORTED_CLUSTERCLASSES=(
1616
for clusterclass in ${SUPPORTED_CLUSTERCLASSES[@]}; do
1717
# clusterctl expects clusterclass not have the "cluster-template" prefix
1818
# except for the actual cluster template using the clusterclass
19-
echo "****** Generating clusterclass-${clusterclass} flavor ******"
19+
echo "****** Generating ${clusterclass} flavor ******"
2020
kustomize build "${FLAVORS_DIR}/${clusterclass}" > "${REPO_ROOT}/templates/${clusterclass}.yaml"
2121
cp "${FLAVORS_DIR}/${clusterclass}/cluster-template.yaml" "${REPO_ROOT}/templates/cluster-template-${clusterclass}.yaml"
2222
done

internal/controller/linodecluster_controller_helpers.go

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -87,51 +87,62 @@ func removeMachineFromNB(ctx context.Context, logger logr.Logger, clusterScope *
8787
}
8888

8989
func getIPPortCombo(cscope *scope.ClusterScope) (ipPortComboList []string) {
90-
apiserverLBPort := services.DefaultApiserverLBPort
91-
if cscope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort != 0 {
92-
apiserverLBPort = cscope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort
93-
}
94-
95-
// Check if we're using VPC
96-
useVPCIps := cscope.LinodeCluster.Spec.Network.NodeBalancerBackendIPv4Range != "" && cscope.LinodeCluster.Spec.VPCRef != nil
90+
apiServerLBPort := services.DetermineAPIServerLBPort(cscope)
91+
useVPCIPs := services.ShouldUseVPC(cscope)
9792

9893
for _, eachMachine := range cscope.LinodeMachines.Items {
99-
// First try to find VPC IPs if we're using VPC
100-
if useVPCIps {
101-
vpcIPFound := false
102-
for _, IPs := range eachMachine.Status.Addresses {
103-
// Look for internal IPs that are NOT 192.168.* (likely VPC IPs)
104-
if IPs.Type == clusterv1.MachineInternalIP && !util.IsLinodePrivateIP(IPs.Address) {
105-
vpcIPFound = true
106-
ipPortComboList = append(ipPortComboList, fmt.Sprintf("%s:%d", IPs.Address, apiserverLBPort))
107-
for _, portConfig := range cscope.LinodeCluster.Spec.Network.AdditionalPorts {
108-
ipPortComboList = append(ipPortComboList, fmt.Sprintf("%s:%d", IPs.Address, portConfig.Port))
109-
}
110-
break // Use first VPC IP found for this machine
111-
}
112-
}
94+
var selectedIP string
11395

114-
// If we found a VPC IP for this machine, continue to the next machine
115-
if vpcIPFound {
116-
continue
96+
if useVPCIPs {
97+
if ip, ok := findFirstVPCInternalIP(eachMachine.Status.Addresses); ok {
98+
selectedIP = ip
11799
}
118100
}
119101

120-
// Fall back to original behavior for this machine if no VPC IP found or not using VPC
121-
for _, IPs := range eachMachine.Status.Addresses {
122-
if IPs.Type != clusterv1.MachineInternalIP || !util.IsLinodePrivateIP(IPs.Address) {
123-
continue
102+
if selectedIP == "" {
103+
if ip, ok := findFirstPrivateInternalIP(eachMachine.Status.Addresses); ok {
104+
selectedIP = ip
124105
}
125-
ipPortComboList = append(ipPortComboList, fmt.Sprintf("%s:%d", IPs.Address, apiserverLBPort))
126-
for _, portConfig := range cscope.LinodeCluster.Spec.Network.AdditionalPorts {
127-
ipPortComboList = append(ipPortComboList, fmt.Sprintf("%s:%d", IPs.Address, portConfig.Port))
128-
}
129-
break // Use first 192.168.* IP found for this machine
106+
}
107+
108+
if selectedIP != "" {
109+
ipPortComboList = append(ipPortComboList, buildPortCombosForIP(selectedIP, apiServerLBPort, cscope.LinodeCluster.Spec.Network.AdditionalPorts)...)
130110
}
131111
}
112+
132113
return ipPortComboList
133114
}
134115

116+
// findFirstVPCInternalIP returns the first internal IP that is not in Linode's private 192.168.* range.
117+
func findFirstVPCInternalIP(addresses []clusterv1.MachineAddress) (string, bool) {
118+
for _, addr := range addresses {
119+
if addr.Type == clusterv1.MachineInternalIP && !util.IsLinodePrivateIP(addr.Address) {
120+
return addr.Address, true
121+
}
122+
}
123+
return "", false
124+
}
125+
126+
// findFirstPrivateInternalIP returns the first internal IP in Linode's private 192.168.* range.
127+
func findFirstPrivateInternalIP(addresses []clusterv1.MachineAddress) (string, bool) {
128+
for _, addr := range addresses {
129+
if addr.Type == clusterv1.MachineInternalIP && util.IsLinodePrivateIP(addr.Address) {
130+
return addr.Address, true
131+
}
132+
}
133+
return "", false
134+
}
135+
136+
// buildPortCombosForIP composes ip:port pairs for the API server port and any additional ports.
137+
func buildPortCombosForIP(ip string, apiServerLBPort int, additionalPorts []infrav1alpha2.LinodeNBPortConfig) []string {
138+
results := make([]string, 0, 1+len(additionalPorts))
139+
results = append(results, fmt.Sprintf("%s:%d", ip, apiServerLBPort))
140+
for _, portConfig := range additionalPorts {
141+
results = append(results, fmt.Sprintf("%s:%d", ip, portConfig.Port))
142+
}
143+
return results
144+
}
145+
135146
func linodeMachineToLinodeCluster(tracedClient client.Client, logger logr.Logger) handler.MapFunc {
136147
logger = logger.WithName("LinodeClusterReconciler").WithName("linodeMachineToLinodeCluster")
137148

@@ -188,10 +199,7 @@ func handleDNS(clusterScope *scope.ClusterScope) {
188199
subDomain = clusterScope.LinodeCluster.Spec.Network.DNSSubDomainOverride
189200
}
190201
dnsHost := subDomain + "." + clusterSpec.Network.DNSRootDomain
191-
apiLBPort := services.DefaultApiserverLBPort
192-
if clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort != 0 {
193-
apiLBPort = clusterScope.LinodeCluster.Spec.Network.ApiserverLoadBalancerPort
194-
}
202+
apiLBPort := services.DetermineAPIServerLBPort(clusterScope)
195203
clusterScope.LinodeCluster.Spec.ControlPlaneEndpoint = clusterv1.APIEndpoint{
196204
Host: dnsHost,
197205
Port: int32(apiLBPort), // #nosec G115: Integer overflow conversion is safe for port numbers

internal/controller/linodecluster_controller_helpers_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func TestGetIPPortCombo(t *testing.T) {
9393
LinodeCluster: &infrav1alpha2.LinodeCluster{
9494
Spec: infrav1alpha2.LinodeClusterSpec{
9595
Network: infrav1alpha2.NetworkSpec{
96+
EnableVPCBackends: true,
9697
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
9798
},
9899
VPCRef: &corev1.ObjectReference{
@@ -127,6 +128,7 @@ func TestGetIPPortCombo(t *testing.T) {
127128
LinodeCluster: &infrav1alpha2.LinodeCluster{
128129
Spec: infrav1alpha2.LinodeClusterSpec{
129130
Network: infrav1alpha2.NetworkSpec{
131+
EnableVPCBackends: true,
130132
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
131133
},
132134
VPCRef: &corev1.ObjectReference{
@@ -192,6 +194,7 @@ func TestGetIPPortCombo(t *testing.T) {
192194
LinodeCluster: &infrav1alpha2.LinodeCluster{
193195
Spec: infrav1alpha2.LinodeClusterSpec{
194196
Network: infrav1alpha2.NetworkSpec{
197+
EnableVPCBackends: true,
195198
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
196199
AdditionalPorts: []infrav1alpha2.LinodeNBPortConfig{
197200
{
@@ -227,6 +230,7 @@ func TestGetIPPortCombo(t *testing.T) {
227230
LinodeCluster: &infrav1alpha2.LinodeCluster{
228231
Spec: infrav1alpha2.LinodeClusterSpec{
229232
Network: infrav1alpha2.NetworkSpec{
233+
EnableVPCBackends: true,
230234
NodeBalancerBackendIPv4Range: "10.0.0.0/24",
231235
},
232236
VPCRef: &corev1.ObjectReference{

0 commit comments

Comments
 (0)