Skip to content

Commit

Permalink
Merge branch 'main' into linodemachine-vpcref
Browse files Browse the repository at this point in the history
  • Loading branch information
Khaja Omer committed Oct 25, 2024
2 parents 5b1b76a + 8684d43 commit d2bffc6
Show file tree
Hide file tree
Showing 14 changed files with 526 additions and 398 deletions.
14 changes: 13 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ linters-settings:
# tokens count to trigger issue, 150 by default
threshold: 100

depguard:
rules:
main:
files:
- "$all"
- "!$test"
deny:
- pkg: "reflect"
desc: "Reflection is never clear."
- pkg: "gob"
desc: "Please convert types manually"

goconst:
# minimal length of string constant, 3 by default
min-len: 3
Expand Down Expand Up @@ -132,7 +144,7 @@ linters:
- contextcheck
- cyclop
- decorder
# - depguard
- depguard
- dogsled
# - dupl
- dupword
Expand Down
4 changes: 4 additions & 0 deletions api/v1alpha1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,7 @@ func Convert_v1alpha2_LinodeClusterSpec_To_v1alpha1_LinodeClusterSpec(in *infras
// VLAN is not supported in v1alpha1
return autoConvert_v1alpha2_LinodeClusterSpec_To_v1alpha1_LinodeClusterSpec(in, out, scope)
}

func Convert_v1alpha2_VPCSubnetCreateOptions_To_v1alpha1_VPCSubnetCreateOptions(in *infrastructurev1alpha2.VPCSubnetCreateOptions, out *VPCSubnetCreateOptions, scope conversion.Scope) error {
return autoConvert_v1alpha2_VPCSubnetCreateOptions_To_v1alpha1_VPCSubnetCreateOptions(in, out, scope)
}
64 changes: 50 additions & 14 deletions api/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion api/v1alpha2/linodevpc_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ type LinodeVPCSpec struct {
Description string `json:"description,omitempty"`
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
Region string `json:"region"`
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
// +optional
Subnets []VPCSubnetCreateOptions `json:"subnets,omitempty"`

Expand All @@ -54,6 +53,9 @@ type VPCSubnetCreateOptions struct {
Label string `json:"label,omitempty"`
// +optional
IPv4 string `json:"ipv4,omitempty"`
// SubnetID is subnet id for the subnet
// +optional
SubnetID int `json:"subnetID,omitempty"`
}

// LinodeVPCStatus defines the observed state of LinodeVPC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,11 @@ spec:
maxLength: 63
minLength: 3
type: string
subnetID:
description: SubnetID is subnet id for the subnet
type: integer
type: object
type: array
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
vpcID:
type: integer
required:
Expand Down
106 changes: 55 additions & 51 deletions controller/linodemachine_controller_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ limitations under the License.
package controller

import (
"bytes"
"context"
b64 "encoding/base64"
"encoding/gob"
"errors"
"fmt"
"net/http"
"net/netip"
"slices"
"sort"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -171,12 +168,6 @@ func buildInstanceAddrs(ctx context.Context, machineScope *scope.MachineScope, i
return nil, fmt.Errorf("get instance ips: %w", err)
}

// get the default instance config
configs, err := machineScope.LinodeClient.ListInstanceConfigs(ctx, instanceID, &linodego.ListOptions{})
if err != nil || len(configs) == 0 {
return nil, fmt.Errorf("list instance configs: %w", err)
}

ips := []clusterv1.MachineAddress{}
// check if a node has public ipv4 ip and store it
if len(addresses.IPv4.Public) == 0 {
Expand All @@ -199,21 +190,32 @@ func buildInstanceAddrs(ctx context.Context, machineScope *scope.MachineScope, i
Type: clusterv1.MachineExternalIP,
})

// Iterate over interfaces in config and find VPC or VLAN specific ips
for _, iface := range configs[0].Interfaces {
if iface.VPCID != nil && iface.IPv4.VPC != "" {
// check if a node has vpc specific ip and store it
for _, vpcIP := range addresses.IPv4.VPC {
if *vpcIP.Address != "" {
ips = append(ips, clusterv1.MachineAddress{
Address: iface.IPv4.VPC,
Address: *vpcIP.Address,
Type: clusterv1.MachineInternalIP,
})
}
}

if iface.Purpose == linodego.InterfacePurposeVLAN {
// vlan addresses have a /11 appended to them - we should strip it out.
ips = append(ips, clusterv1.MachineAddress{
Address: netip.MustParsePrefix(iface.IPAMAddress).Addr().String(),
Type: clusterv1.MachineInternalIP,
})
if machineScope.LinodeCluster.Spec.Network.UseVlan {
// get the default instance config
configs, err := machineScope.LinodeClient.ListInstanceConfigs(ctx, instanceID, &linodego.ListOptions{})
if err != nil || len(configs) == 0 {
return nil, fmt.Errorf("list instance configs: %w", err)
}

// Iterate over interfaces in config and find VLAN specific ips
for _, iface := range configs[0].Interfaces {
if iface.Purpose == linodego.InterfacePurposeVLAN {
// vlan addresses have a /11 appended to them - we should strip it out.
ips = append(ips, clusterv1.MachineAddress{
Address: netip.MustParsePrefix(iface.IPAMAddress).Addr().String(),
Type: clusterv1.MachineInternalIP,
})
}
}
}

Expand Down Expand Up @@ -405,29 +407,17 @@ func getVPCInterfaceConfig(ctx context.Context, machineScope *scope.MachineScope
return nil, errors.New("vpc is not available")
}

var subnetID int
vpc, err := machineScope.LinodeClient.GetVPC(ctx, *linodeVPC.Spec.VPCID)
if err != nil {
logger.Error(err, "Failed to fetch LinodeVPC")

return nil, err
}
if vpc == nil {
logger.Error(nil, "Failed to fetch VPC")

return nil, errors.New("failed to fetch VPC")
}
if len(vpc.Subnets) == 0 {
if len(linodeVPC.Spec.Subnets) == 0 {
logger.Error(nil, "Failed to find subnet")

return nil, errors.New("failed to find subnet")
}
// Place node into the least busy subnet
sort.Slice(vpc.Subnets, func(i, j int) bool {
return len(vpc.Subnets[i].Linodes) > len(vpc.Subnets[j].Linodes)
})

subnetID = vpc.Subnets[0].ID
subnetID := linodeVPC.Spec.Subnets[0].SubnetID
if subnetID == 0 {
return nil, errors.New("failed to find subnet as subnet id set is 0")
}

for i, netInterface := range interfaces {
if netInterface.Purpose == linodego.InterfacePurposeVPC {
interfaces[i].SubnetID = &subnetID
Expand All @@ -446,21 +436,35 @@ func getVPCInterfaceConfig(ctx context.Context, machineScope *scope.MachineScope
}

func linodeMachineSpecToInstanceCreateConfig(machineSpec infrav1alpha2.LinodeMachineSpec) *linodego.InstanceCreateOptions {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(machineSpec)
if err != nil {
return nil
}

var createConfig linodego.InstanceCreateOptions
dec := gob.NewDecoder(&buf)
err = dec.Decode(&createConfig)
if err != nil {
return nil
interfaces := make([]linodego.InstanceConfigInterfaceCreateOptions, len(machineSpec.Interfaces))
for idx, iface := range machineSpec.Interfaces {
interfaces[idx] = linodego.InstanceConfigInterfaceCreateOptions{
IPAMAddress: iface.IPAMAddress,
Label: iface.Label,
Purpose: iface.Purpose,
Primary: iface.Primary,
SubnetID: iface.SubnetID,
IPRanges: iface.IPRanges,
}
}
privateIP := false
if machineSpec.PrivateIP != nil {
privateIP = *machineSpec.PrivateIP
}
return &linodego.InstanceCreateOptions{
Region: machineSpec.Region,
Type: machineSpec.Type,
AuthorizedKeys: machineSpec.AuthorizedKeys,
AuthorizedUsers: machineSpec.AuthorizedUsers,
RootPass: machineSpec.RootPass,
Image: machineSpec.Image,
Interfaces: interfaces,
PrivateIP: privateIP,
Tags: machineSpec.Tags,
FirewallID: machineSpec.FirewallID,
DiskEncryption: linodego.InstanceDiskEncryption(machineSpec.DiskEncryption),
Group: machineSpec.Group,
}

return &createConfig
}

func setUserData(ctx context.Context, machineScope *scope.MachineScope, createConfig *linodego.InstanceCreateOptions, logger logr.Logger) error {
Expand Down
15 changes: 0 additions & 15 deletions controller/linodemachine_controller_helpers_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package controller

import (
"bytes"
"context"
b64 "encoding/base64"
"encoding/gob"
"fmt"
"testing"

"github.com/go-logr/logr"
"github.com/linode/linodego"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -62,18 +59,6 @@ func TestLinodeMachineSpecToCreateInstanceConfig(t *testing.T) {

createConfig := linodeMachineSpecToInstanceCreateConfig(machineSpec)
assert.NotNil(t, createConfig, "Failed to convert LinodeMachineSpec to InstanceCreateOptions")

var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(createConfig)
require.NoError(t, err, "Failed to encode InstanceCreateOptions")

var actualMachineSpec infrav1alpha2.LinodeMachineSpec
dec := gob.NewDecoder(&buf)
err = dec.Decode(&actualMachineSpec)
require.NoError(t, err, "Failed to decode LinodeMachineSpec")

assert.Equal(t, machineSpec, actualMachineSpec)
}

func TestSetUserData(t *testing.T) {
Expand Down
Loading

0 comments on commit d2bffc6

Please sign in to comment.