Skip to content

Commit fd939a4

Browse files
committed
add some comments and handle network helper
1 parent 22ba316 commit fd939a4

9 files changed

+224
-129
lines changed

api/v1alpha2/linodemachine_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ type LinodeMachineSpec struct {
5959
BackupID int `json:"backupID,omitempty"`
6060
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
6161
Image string `json:"image,omitempty"`
62+
// Interfaces is a list of legacy network interfaces to use for the instance.
6263
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
6364
Interfaces []InstanceConfigInterfaceCreateOptions `json:"interfaces,omitempty"`
65+
// LinodeInterfaces is a list of Linode network interfaces to use for the instance. Requires Linode Interfaces beta opt-in to use.
6466
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
6567
// +kubebuilder:object:generate=true
6668
LinodeInterfaces []LinodeInterfaceCreateOptions `json:"linodeInterfaces,omitempty"`

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ spec:
238238
- linode
239239
type: string
240240
interfaces:
241+
description: Interfaces is a list of legacy network interfaces to
242+
use for the instance.
241243
items:
242244
description: InstanceConfigInterfaceCreateOptions defines network
243245
interface config
@@ -311,6 +313,9 @@ spec:
311313
- message: Value is immutable
312314
rule: self == oldSelf
313315
linodeInterfaces:
316+
description: LinodeInterfaces is a list of Linode network interfaces
317+
to use for the instance. Requires Linode Interfaces beta opt-in
318+
to use.
314319
items:
315320
description: LinodeInterfaceCreateOptions defines the linode network
316321
interface config

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ spec:
229229
- linode
230230
type: string
231231
interfaces:
232+
description: Interfaces is a list of legacy network interfaces
233+
to use for the instance.
232234
items:
233235
description: InstanceConfigInterfaceCreateOptions defines
234236
network interface config
@@ -303,6 +305,9 @@ spec:
303305
- message: Value is immutable
304306
rule: self == oldSelf
305307
linodeInterfaces:
308+
description: LinodeInterfaces is a list of Linode network
309+
interfaces to use for the instance. Requires Linode Interfaces
310+
beta opt-in to use.
306311
items:
307312
description: LinodeInterfaceCreateOptions defines the linode
308313
network interface config

docs/src/reference/out.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ _Appears in:_
662662
| `authorizedUsers` _string array_ | | | |
663663
| `backupID` _integer_ | | | |
664664
| `image` _string_ | | | |
665-
| `interfaces` _[InstanceConfigInterfaceCreateOptions](#instanceconfiginterfacecreateoptions) array_ | | | |
666-
| `linodeInterfaces` _[LinodeInterfaceCreateOptions](#linodeinterfacecreateoptions) array_ | | | |
665+
| `interfaces` _[InstanceConfigInterfaceCreateOptions](#instanceconfiginterfacecreateoptions) array_ | Interfaces is a list of legacy network interfaces to use for the instance. | | |
666+
| `linodeInterfaces` _[LinodeInterfaceCreateOptions](#linodeinterfacecreateoptions) array_ | LinodeInterfaces is a list of Linode network interfaces to use for the instance. Requires Linode Interfaces beta opt-in to use. | | |
667667
| `backupsEnabled` _boolean_ | | | |
668668
| `privateIP` _boolean_ | | | |
669669
| `tags` _string array_ | Tags is a list of tags to apply to the Linode instance. | | |

internal/controller/linodemachine_controller.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,11 +623,18 @@ func (r *LinodeMachineReconciler) reconcilePreflightConfigure(ctx context.Contex
623623
if machineScope.LinodeMachine.Spec.Configuration != nil && machineScope.LinodeMachine.Spec.Configuration.Kernel != "" {
624624
configData.Kernel = machineScope.LinodeMachine.Spec.Configuration.Kernel
625625
}
626+
// helpers.network does not work on instances using the new linode interfaces.
626627
// For cases where the network helper is not enabled on account level, we can enable it per instance level
627628
// Default is true, so we only need to update if it's explicitly set to false
628-
if machineScope.LinodeMachine.Spec.NetworkHelper != nil {
629-
configData.Helpers = &linodego.InstanceConfigHelpers{
630-
Network: *machineScope.LinodeMachine.Spec.NetworkHelper,
629+
if machineScope.LinodeMachine.Spec.InterfaceGeneration != linodego.GenerationLinode {
630+
if machineScope.LinodeMachine.Spec.NetworkHelper != nil {
631+
configData.Helpers = &linodego.InstanceConfigHelpers{
632+
Network: *machineScope.LinodeMachine.Spec.NetworkHelper,
633+
}
634+
} else {
635+
configData.Helpers = &linodego.InstanceConfigHelpers{
636+
Network: true,
637+
}
631638
}
632639
}
633640

internal/controller/linodemachine_controller_helpers.go

Lines changed: 112 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,24 @@ func retryIfTransient(err error, logger logr.Logger) (ctrl.Result, error) {
8383
func fillCreateConfig(createConfig *linodego.InstanceCreateOptions, machineScope *scope.MachineScope) {
8484
// This will only be empty if no interfaces or linodeInterfaces were specified in the LinodeMachine spec.
8585
// In that case we default to legacy interfaces.
86-
if createConfig.InterfaceGeneration == "" {
86+
switch createConfig.InterfaceGeneration {
87+
case "":
8788
createConfig.InterfaceGeneration = linodego.GenerationLegacyConfig
89+
case linodego.GenerationLinode:
90+
// networkHelper is only applicable for Linode interfaces.
91+
// legacy interfaces have nework helper configured in reconcilePreflightConfigure at the instance level.
92+
if machineScope.LinodeMachine.Spec.NetworkHelper != nil {
93+
createConfig.NetworkHelper = machineScope.LinodeMachine.Spec.NetworkHelper
94+
} else {
95+
createConfig.NetworkHelper = ptr.To(true)
96+
}
8897
}
98+
8999
if machineScope.LinodeMachine.Spec.PrivateIP != nil {
90100
createConfig.PrivateIP = *machineScope.LinodeMachine.Spec.PrivateIP
91-
} else {
92-
if createConfig.InterfaceGeneration == linodego.GenerationLegacyConfig {
93-
// Supported only for legacy network interfaces.
94-
createConfig.PrivateIP = true
95-
} else {
96-
// Network Helper is not supported for the new network interfaces.
97-
createConfig.NetworkHelper = nil
98-
}
101+
} else if createConfig.InterfaceGeneration != linodego.GenerationLinode {
102+
// Supported only for legacy network interfaces.
103+
createConfig.PrivateIP = true
99104
}
100105

101106
if createConfig.Tags == nil {
@@ -631,7 +636,7 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
631636
for _, subnet := range linodeVPC.Spec.Subnets {
632637
if subnet.Label == subnetName {
633638
subnetID = subnet.SubnetID
634-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(subnet.IPv6))
639+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(subnet.IPv6))
635640
break
636641
}
637642
}
@@ -641,7 +646,7 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
641646
}
642647
} else {
643648
subnetID = linodeVPC.Spec.Subnets[0].SubnetID // get first subnet if nothing specified
644-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(linodeVPC.Spec.Subnets[0].IPv6))
649+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(linodeVPC.Spec.Subnets[0].IPv6))
645650
}
646651

647652
if subnetID == 0 {
@@ -731,7 +736,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
731736
for _, subnet := range vpc.Subnets {
732737
if subnet.Label == subnetName {
733738
subnetID = subnet.ID
734-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(subnet.IPv6))
739+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(subnet.IPv6))
735740
break
736741
}
737742
}
@@ -740,7 +745,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
740745
}
741746
} else {
742747
subnetID = vpc.Subnets[0].ID
743-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(vpc.Subnets[0].IPv6))
748+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(vpc.Subnets[0].IPv6))
744749
}
745750

746751
// Check if a VPC interface already exists
@@ -890,12 +895,12 @@ func getMachineIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubne
890895
return intfOpts
891896
}
892897

893-
// getVPCInterfaceIPv6Config returns the IPv6 configuration for a LinodeMachine.
898+
// getVPCLinodeInterfaceIPv6Config returns the IPv6 configuration for a LinodeMachine.
894899
// It checks the LinodeMachine's IPv6Options for SLAAC and Ranges settings.
895900
// If `EnableSLAAC` is set, it will enable SLAAC with the default IPv6 CIDR range.
896901
// If `EnableRanges` is set, it will enable IPv6 ranges with the default IPv6 CIDR range.
897902
// If `IsPublicIPv6` is set, it will be used to determine if the IPv6 range should be publicly routable or not.
898-
func getVPCInterfaceIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubnet int) *linodego.VPCInterfaceIPv6CreateOptions {
903+
func getVPCLinodeInterfaceIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubnet int) *linodego.VPCInterfaceIPv6CreateOptions {
899904
intfOpts := &linodego.VPCInterfaceIPv6CreateOptions{}
900905

901906
// If there are no IPv6 ranges in the subnet or if IPv6 options are not specified, return nil.
@@ -928,8 +933,6 @@ func getVPCInterfaceIPv6Config(machineScope *scope.MachineScope, numIPv6RangesIn
928933

929934
// Unfortunately, this is necessary since DeepCopy can't be generated for linodego.LinodeInterfaceCreateOptions
930935
// so here we manually create the options for Linode interfaces.
931-
//
932-
//nolint:gocognit,cyclop,gocritic,nestif,nolintlint // Also, unfortunately, this cannot be made any reasonably simpler with how complicated the linodego struct is
933936
func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfaceCreateOptions) []linodego.LinodeInterfaceCreateOptions {
934937
linodeInterfaces := make([]linodego.LinodeInterfaceCreateOptions, len(createOpts))
935938
for idx, iface := range createOpts {
@@ -943,91 +946,11 @@ func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfa
943946
}
944947
// Handle VPC
945948
if iface.VPC != nil {
946-
var (
947-
ipv4Addrs []linodego.VPCInterfaceIPv4AddressCreateOptions
948-
ipv4Ranges []linodego.VPCInterfaceIPv4RangeCreateOptions
949-
ipv6Ranges []linodego.VPCInterfaceIPv6RangeCreateOptions
950-
ipv6SLAAC []linodego.VPCInterfaceIPv6SLAACCreateOptions
951-
ipv6IsPublic bool
952-
)
953-
if iface.VPC.IPv4 != nil {
954-
for _, addr := range iface.VPC.IPv4.Addresses {
955-
ipv4Addrs = append(ipv4Addrs, linodego.VPCInterfaceIPv4AddressCreateOptions{
956-
Address: addr.Address,
957-
Primary: addr.Primary,
958-
NAT1To1Address: addr.NAT1To1Address,
959-
})
960-
}
961-
for _, rng := range iface.VPC.IPv4.Ranges {
962-
ipv4Ranges = append(ipv4Ranges, linodego.VPCInterfaceIPv4RangeCreateOptions{
963-
Range: rng.Range,
964-
})
965-
}
966-
} else {
967-
// If no IPv4 addresses are specified, we set a default NAT1To1 address to "any"
968-
ipv4Addrs = []linodego.VPCInterfaceIPv4AddressCreateOptions{
969-
{
970-
Primary: ptr.To(true),
971-
NAT1To1Address: ptr.To("auto"),
972-
Address: "auto", // Default to auto-assigned address
973-
},
974-
}
975-
}
976-
if iface.VPC.IPv6 != nil {
977-
for _, slaac := range iface.VPC.IPv6.SLAAC {
978-
ipv6SLAAC = append(ipv6SLAAC, linodego.VPCInterfaceIPv6SLAACCreateOptions{
979-
Range: slaac.Range,
980-
})
981-
}
982-
for _, rng := range iface.VPC.IPv6.Ranges {
983-
ipv6Ranges = append(ipv6Ranges, linodego.VPCInterfaceIPv6RangeCreateOptions{
984-
Range: rng.Range,
985-
})
986-
}
987-
ipv6IsPublic = iface.VPC.IPv6.IsPublic
988-
}
989-
ifaceCreateOpts.VPC = &linodego.VPCInterfaceCreateOptions{
990-
SubnetID: iface.VPC.SubnetID,
991-
IPv4: &linodego.VPCInterfaceIPv4CreateOptions{
992-
Addresses: ipv4Addrs,
993-
Ranges: ipv4Ranges,
994-
},
995-
IPv6: &linodego.VPCInterfaceIPv6CreateOptions{
996-
SLAAC: ipv6SLAAC,
997-
Ranges: ipv6Ranges,
998-
IsPublic: ipv6IsPublic,
999-
},
1000-
}
949+
ifaceCreateOpts.VPC = constructLinodeInterfaceVPC(iface)
1001950
}
1002951
// Handle Public Interface
1003952
if iface.Public != nil {
1004-
var (
1005-
ipv4Addrs []linodego.PublicInterfaceIPv4AddressCreateOptions
1006-
ipv6Ranges []linodego.PublicInterfaceIPv6RangeCreateOptions
1007-
)
1008-
if iface.Public.IPv4 != nil {
1009-
for _, addr := range iface.Public.IPv4.Addresses {
1010-
ipv4Addrs = append(ipv4Addrs, linodego.PublicInterfaceIPv4AddressCreateOptions{
1011-
Address: addr.Address,
1012-
Primary: addr.Primary,
1013-
})
1014-
}
1015-
}
1016-
if iface.Public.IPv6 != nil {
1017-
for _, rng := range iface.Public.IPv6.Ranges {
1018-
ipv6Ranges = append(ipv6Ranges, linodego.PublicInterfaceIPv6RangeCreateOptions{
1019-
Range: rng.Range,
1020-
})
1021-
}
1022-
}
1023-
ifaceCreateOpts.Public = &linodego.PublicInterfaceCreateOptions{
1024-
IPv4: &linodego.PublicInterfaceIPv4CreateOptions{
1025-
Addresses: ipv4Addrs,
1026-
},
1027-
IPv6: &linodego.PublicInterfaceIPv6CreateOptions{
1028-
Ranges: ipv6Ranges,
1029-
},
1030-
}
953+
ifaceCreateOpts.Public = constructLinodeInterfacePublic(iface)
1031954
}
1032955
// Handle Default Route
1033956
if iface.DefaultRoute != nil {
@@ -1044,6 +967,96 @@ func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfa
1044967
return linodeInterfaces
1045968
}
1046969

970+
// constructLinodeInterfaceVPC constructs a Linode VPC interface configuration from the provided LinodeInterfaceCreateOptions.
971+
func constructLinodeInterfaceVPC(iface infrav1alpha2.LinodeInterfaceCreateOptions) *linodego.VPCInterfaceCreateOptions {
972+
var (
973+
ipv4Addrs []linodego.VPCInterfaceIPv4AddressCreateOptions
974+
ipv4Ranges []linodego.VPCInterfaceIPv4RangeCreateOptions
975+
ipv6Ranges []linodego.VPCInterfaceIPv6RangeCreateOptions
976+
ipv6SLAAC []linodego.VPCInterfaceIPv6SLAACCreateOptions
977+
ipv6IsPublic bool
978+
)
979+
if iface.VPC.IPv4 != nil {
980+
for _, addr := range iface.VPC.IPv4.Addresses {
981+
ipv4Addrs = append(ipv4Addrs, linodego.VPCInterfaceIPv4AddressCreateOptions{
982+
Address: addr.Address,
983+
Primary: addr.Primary,
984+
NAT1To1Address: addr.NAT1To1Address,
985+
})
986+
}
987+
for _, rng := range iface.VPC.IPv4.Ranges {
988+
ipv4Ranges = append(ipv4Ranges, linodego.VPCInterfaceIPv4RangeCreateOptions{
989+
Range: rng.Range,
990+
})
991+
}
992+
} else {
993+
// If no IPv4 addresses are specified, we set a default NAT1To1 address to "any"
994+
ipv4Addrs = []linodego.VPCInterfaceIPv4AddressCreateOptions{
995+
{
996+
Primary: ptr.To(true),
997+
NAT1To1Address: ptr.To("auto"),
998+
Address: "auto", // Default to auto-assigned address
999+
},
1000+
}
1001+
}
1002+
if iface.VPC.IPv6 != nil {
1003+
for _, slaac := range iface.VPC.IPv6.SLAAC {
1004+
ipv6SLAAC = append(ipv6SLAAC, linodego.VPCInterfaceIPv6SLAACCreateOptions{
1005+
Range: slaac.Range,
1006+
})
1007+
}
1008+
for _, rng := range iface.VPC.IPv6.Ranges {
1009+
ipv6Ranges = append(ipv6Ranges, linodego.VPCInterfaceIPv6RangeCreateOptions{
1010+
Range: rng.Range,
1011+
})
1012+
}
1013+
ipv6IsPublic = iface.VPC.IPv6.IsPublic
1014+
}
1015+
return &linodego.VPCInterfaceCreateOptions{
1016+
SubnetID: iface.VPC.SubnetID,
1017+
IPv4: &linodego.VPCInterfaceIPv4CreateOptions{
1018+
Addresses: ipv4Addrs,
1019+
Ranges: ipv4Ranges,
1020+
},
1021+
IPv6: &linodego.VPCInterfaceIPv6CreateOptions{
1022+
SLAAC: ipv6SLAAC,
1023+
Ranges: ipv6Ranges,
1024+
IsPublic: ipv6IsPublic,
1025+
},
1026+
}
1027+
}
1028+
1029+
// constructLinodeInterfacePublic constructs a Linode Public interface configuration from the provided LinodeInterfaceCreateOptions.
1030+
func constructLinodeInterfacePublic(iface infrav1alpha2.LinodeInterfaceCreateOptions) *linodego.PublicInterfaceCreateOptions {
1031+
var (
1032+
ipv4Addrs []linodego.PublicInterfaceIPv4AddressCreateOptions
1033+
ipv6Ranges []linodego.PublicInterfaceIPv6RangeCreateOptions
1034+
)
1035+
if iface.Public.IPv4 != nil {
1036+
for _, addr := range iface.Public.IPv4.Addresses {
1037+
ipv4Addrs = append(ipv4Addrs, linodego.PublicInterfaceIPv4AddressCreateOptions{
1038+
Address: addr.Address,
1039+
Primary: addr.Primary,
1040+
})
1041+
}
1042+
}
1043+
if iface.Public.IPv6 != nil {
1044+
for _, rng := range iface.Public.IPv6.Ranges {
1045+
ipv6Ranges = append(ipv6Ranges, linodego.PublicInterfaceIPv6RangeCreateOptions{
1046+
Range: rng.Range,
1047+
})
1048+
}
1049+
}
1050+
return &linodego.PublicInterfaceCreateOptions{
1051+
IPv4: &linodego.PublicInterfaceIPv4CreateOptions{
1052+
Addresses: ipv4Addrs,
1053+
},
1054+
IPv6: &linodego.PublicInterfaceIPv6CreateOptions{
1055+
Ranges: ipv6Ranges,
1056+
},
1057+
}
1058+
}
1059+
10471060
// For converting LinodeMachineSpec to linodego.InstanceCreateOptions. Any defaulting should be done in fillCreateConfig instead
10481061
func linodeMachineSpecToInstanceCreateConfig(machineSpec infrav1alpha2.LinodeMachineSpec, machineTags []string) *linodego.InstanceCreateOptions {
10491062
instCreateOpts := &linodego.InstanceCreateOptions{

0 commit comments

Comments
 (0)