Skip to content

Commit 51eb3fb

Browse files
Merge branch 'main' into network-interfaces
2 parents 5c85408 + dbfb8e6 commit 51eb3fb

23 files changed

+605
-72
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 {

api/v1alpha2/linodemachine_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ type LinodeMachineSpec struct {
7070
PrivateIP *bool `json:"privateIP,omitempty"`
7171
// Tags is a list of tags to apply to the Linode instance.
7272
Tags []string `json:"tags,omitempty"`
73-
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
73+
// FirewallID is the id of the cloud firewall to apply to the Linode Instance
7474
FirewallID int `json:"firewallID,omitempty"`
7575
// OSDisk is configuration for the root disk that includes the OS,
7676
// if not specified this defaults to whatever space is not taken up by the DataDisks

api/v1alpha2/linodemachinetemplate_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ type LinodeMachineTemplateStatus struct {
3333
// +optional
3434
Tags []string `json:"tags,omitempty"`
3535

36+
// Firewall ID that is currently applied to the LinodeMachineTemplate.
37+
// +optional
38+
FirewallID int `json:"firewallID,omitempty"`
39+
3640
// Conditions represent the latest available observations of a LinodeMachineTemplate's current state.
3741
// +optional
3842
Conditions []metav1.Condition `json:"conditions,omitempty"`

clients/clients.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ type LinodeInstanceClient interface {
5656
GetRegion(ctx context.Context, regionID string) (*linodego.Region, error)
5757
GetImage(ctx context.Context, imageID string) (*linodego.Image, error)
5858
GetType(ctx context.Context, typeID string) (*linodego.LinodeType, error)
59+
ListInstanceFirewalls(ctx context.Context, linodeID int, opts *linodego.ListOptions) ([]linodego.Firewall, error)
60+
UpdateInstanceFirewalls(ctx context.Context, linodeID int, opts linodego.InstanceFirewallUpdateOptions) ([]linodego.Firewall, error)
5961
}
6062

6163
// LinodeVPCClient defines the methods that interact with Linode's VPC service.

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

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,9 @@ spec:
164164
- message: Value is immutable
165165
rule: self == oldSelf
166166
firewallID:
167+
description: FirewallID is the id of the cloud firewall to apply to
168+
the Linode Instance
167169
type: integer
168-
x-kubernetes-validations:
169-
- message: Value is immutable
170-
rule: self == oldSelf
171170
firewallRef:
172171
description: FirewallRef is a reference to a firewall object. This
173172
makes the linode use the specified firewall.

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,9 @@ spec:
154154
- message: Value is immutable
155155
rule: self == oldSelf
156156
firewallID:
157+
description: FirewallID is the id of the cloud firewall to
158+
apply to the Linode Instance
157159
type: integer
158-
x-kubernetes-validations:
159-
- message: Value is immutable
160-
rule: self == oldSelf
161160
firewallRef:
162161
description: FirewallRef is a reference to a firewall object.
163162
This makes the linode use the specified firewall.
@@ -697,6 +696,9 @@ spec:
697696
- type
698697
type: object
699698
type: array
699+
firewallID:
700+
description: Firewall ID that is currently applied to the LinodeMachineTemplate.
701+
type: integer
700702
tags:
701703
description: tags that are currently applied to the LinodeMachineTemplate.
702704
items:

0 commit comments

Comments
 (0)