Skip to content

Commit 5166c9a

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

9 files changed

+223
-137
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: 111 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,21 @@ 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
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-
}
100+
} else if createConfig.InterfaceGeneration != linodego.GenerationLinode {
101+
// Supported only for legacy network interfaces.
102+
createConfig.PrivateIP = true
99103
}
100104

101105
if createConfig.Tags == nil {
@@ -631,7 +635,7 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
631635
for _, subnet := range linodeVPC.Spec.Subnets {
632636
if subnet.Label == subnetName {
633637
subnetID = subnet.SubnetID
634-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(subnet.IPv6))
638+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(subnet.IPv6))
635639
break
636640
}
637641
}
@@ -641,7 +645,7 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
641645
}
642646
} else {
643647
subnetID = linodeVPC.Spec.Subnets[0].SubnetID // get first subnet if nothing specified
644-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(linodeVPC.Spec.Subnets[0].IPv6))
648+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(linodeVPC.Spec.Subnets[0].IPv6))
645649
}
646650

647651
if subnetID == 0 {
@@ -656,15 +660,6 @@ func getVPCLinodeInterfaceConfig(ctx context.Context, machineScope *scope.Machin
656660
if !isVPCInterfaceIPv6ConfigEmpty(ipv6Config) {
657661
linodeInterfaces[iface].VPC.IPv6 = ipv6Config
658662
}
659-
if netInterface.VPC.IPv4 == nil {
660-
linodeInterfaces[iface].VPC.IPv4 = &linodego.VPCInterfaceIPv4CreateOptions{
661-
Addresses: []linodego.VPCInterfaceIPv4AddressCreateOptions{{
662-
Primary: ptr.To(true),
663-
NAT1To1Address: ptr.To("auto"),
664-
Address: "auto",
665-
}},
666-
}
667-
}
668663
return nil, nil //nolint:nilnil // it is important we don't return an interface if a VPC interface already exists
669664
}
670665
}
@@ -731,7 +726,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
731726
for _, subnet := range vpc.Subnets {
732727
if subnet.Label == subnetName {
733728
subnetID = subnet.ID
734-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(subnet.IPv6))
729+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(subnet.IPv6))
735730
break
736731
}
737732
}
@@ -740,7 +735,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
740735
}
741736
} else {
742737
subnetID = vpc.Subnets[0].ID
743-
ipv6Config = getVPCInterfaceIPv6Config(machineScope, len(vpc.Subnets[0].IPv6))
738+
ipv6Config = getVPCLinodeInterfaceIPv6Config(machineScope, len(vpc.Subnets[0].IPv6))
744739
}
745740

746741
// Check if a VPC interface already exists
@@ -762,6 +757,7 @@ func getVPCLinodeInterfaceConfigFromDirectID(ctx context.Context, machineScope *
762757
Addresses: []linodego.VPCInterfaceIPv4AddressCreateOptions{{
763758
Primary: ptr.To(true),
764759
NAT1To1Address: ptr.To("auto"),
760+
Address: "auto",
765761
}},
766762
},
767763
},
@@ -890,12 +886,12 @@ func getMachineIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubne
890886
return intfOpts
891887
}
892888

893-
// getVPCInterfaceIPv6Config returns the IPv6 configuration for a LinodeMachine.
889+
// getVPCLinodeInterfaceIPv6Config returns the IPv6 configuration for a LinodeMachine.
894890
// It checks the LinodeMachine's IPv6Options for SLAAC and Ranges settings.
895891
// If `EnableSLAAC` is set, it will enable SLAAC with the default IPv6 CIDR range.
896892
// If `EnableRanges` is set, it will enable IPv6 ranges with the default IPv6 CIDR range.
897893
// 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 {
894+
func getVPCLinodeInterfaceIPv6Config(machineScope *scope.MachineScope, numIPv6RangesInSubnet int) *linodego.VPCInterfaceIPv6CreateOptions {
899895
intfOpts := &linodego.VPCInterfaceIPv6CreateOptions{}
900896

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

929925
// Unfortunately, this is necessary since DeepCopy can't be generated for linodego.LinodeInterfaceCreateOptions
930926
// 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
933927
func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfaceCreateOptions) []linodego.LinodeInterfaceCreateOptions {
934928
linodeInterfaces := make([]linodego.LinodeInterfaceCreateOptions, len(createOpts))
935929
for idx, iface := range createOpts {
@@ -943,91 +937,11 @@ func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfa
943937
}
944938
// Handle VPC
945939
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-
}
940+
ifaceCreateOpts.VPC = constructLinodeInterfaceVPC(iface)
1001941
}
1002942
// Handle Public Interface
1003943
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-
}
944+
ifaceCreateOpts.Public = constructLinodeInterfacePublic(iface)
1031945
}
1032946
// Handle Default Route
1033947
if iface.DefaultRoute != nil {
@@ -1044,6 +958,96 @@ func constructLinodeInterfaceCreateOpts(createOpts []infrav1alpha2.LinodeInterfa
1044958
return linodeInterfaces
1045959
}
1046960

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

0 commit comments

Comments
 (0)