Skip to content

Commit 3405cf9

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

9 files changed

+219
-123
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: 107 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,22 @@ func fillCreateConfig(createConfig *linodego.InstanceCreateOptions, machineScope
8585
// In that case we default to legacy interfaces.
8686
if createConfig.InterfaceGeneration == "" {
8787
createConfig.InterfaceGeneration = linodego.GenerationLegacyConfig
88+
} else if createConfig.InterfaceGeneration == linodego.GenerationLinode {
89+
// networkHelper is only applicable for Linode interfaces.
90+
// legacy interfaces have nework helper configured in reconcilePreflightConfigure at the instance level.
91+
if machineScope.LinodeMachine.Spec.NetworkHelper != nil {
92+
createConfig.NetworkHelper = machineScope.LinodeMachine.Spec.NetworkHelper
93+
} else {
94+
createConfig.NetworkHelper = ptr.To(true)
95+
}
8896
}
97+
8998
if machineScope.LinodeMachine.Spec.PrivateIP != nil {
9099
createConfig.PrivateIP = *machineScope.LinodeMachine.Spec.PrivateIP
91100
} else {
92101
if createConfig.InterfaceGeneration == linodego.GenerationLegacyConfig {
93102
// Supported only for legacy network interfaces.
94103
createConfig.PrivateIP = true
95-
} else {
96-
// Network Helper is not supported for the new network interfaces.
97-
createConfig.NetworkHelper = nil
98104
}
99105
}
100106

@@ -631,7 +637,7 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
631637
for _, subnet := range linodeVPC.Spec.Subnets {
632638
if subnet.Label == subnetName {
633639
subnetID = subnet.SubnetID
634-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(subnet.IPv6))
640+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(subnet.IPv6))
635641
break
636642
}
637643
}
@@ -641,7 +647,7 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
641647
}
642648
} else {
643649
subnetID = linodeVPC.Spec.Subnets[0].SubnetID // get first subnet if nothing specified
644-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(linodeVPC.Spec.Subnets[0].IPv6))
650+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(linodeVPC.Spec.Subnets[0].IPv6))
645651
}
646652

647653
if subnetID == 0 {
@@ -731,7 +737,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
731737
for _, subnet := range vpc.Subnets {
732738
if subnet.Label == subnetName {
733739
subnetID = subnet.ID
734-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(subnet.IPv6))
740+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(subnet.IPv6))
735741
break
736742
}
737743
}
@@ -740,7 +746,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
740746
}
741747
} else {
742748
subnetID = vpc.Subnets[0].ID
743-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(vpc.Subnets[0].IPv6))
749+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(vpc.Subnets[0].IPv6))
744750
}
745751

746752
// Check if a VPC interface already exists
@@ -890,12 +896,12 @@ func getMachineIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubne
890896
return intfOpts
891897
}
892898

893-
// getVPCInterfaceIPv6Config returns the IPv6 configuration for a LinodeMachine.
899+
// getVPCLinodeInterfaceIPv6Config returns the IPv6 configuration for a LinodeMachine.
894900
// It checks the LinodeMachine's IPv6Options for SLAAC and Ranges settings.
895901
// If `EnableSLAAC` is set, it will enable SLAAC with the default IPv6 CIDR range.
896902
// If `EnableRanges` is set, it will enable IPv6 ranges with the default IPv6 CIDR range.
897903
// 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 {
904+
func getVPCLinodeInterfaceIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubnet int) *linodego.VPCInterfaceIPv6CreateOptions {
899905
intfOpts := &linodego.VPCInterfaceIPv6CreateOptions{}
900906

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

929935
// Unfortunately, this is necessary since DeepCopy can't be generated for linodego.LinodeInterfaceCreateOptions
930936
// 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
933937
func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfaceCreateOptions) []linodego.LinodeInterfaceCreateOptions {
934938
linodeInterfaces := make([]linodego.LinodeInterfaceCreateOptions, len(createOpts))
935939
for idx, iface := range createOpts {
@@ -943,91 +947,11 @@ func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfa
943947
}
944948
// Handle VPC
945949
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-
}
950+
ifaceCreateOpts.VPC = constructLinodeInterfaceVPC(iface)
1001951
}
1002952
// Handle Public Interface
1003953
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-
}
954+
ifaceCreateOpts.Public = constructLinodeInterfacePublic(iface)
1031955
}
1032956
// Handle Default Route
1033957
if iface.DefaultRoute != nil {
@@ -1044,6 +968,96 @@ func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfa
1044968
return linodeInterfaces
1045969
}
1046970

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

0 commit comments

Comments
 (0)