Skip to content

Commit

Permalink
Merge pull request #2 from newrelic-forks/multiple-nics
Browse files Browse the repository at this point in the history
Multiple NIC support
  • Loading branch information
brianlieberman authored Jun 22, 2022
2 parents 70a94ec + 7bd6b24 commit 9ab3955
Show file tree
Hide file tree
Showing 35 changed files with 1,006 additions and 84 deletions.
5 changes: 5 additions & 0 deletions api/v1alpha3/azuremachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ func (src *AzureMachine) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Image.SharedGallery.SKU = restored.Spec.Image.SharedGallery.SKU
}


if restored.Spec.NetworkInterfaces != nil {
dst.Spec.NetworkInterfaces = restored.Spec.NetworkInterfaces
}

if dst.Spec.Image != nil && restored.Spec.Image.ComputeGallery != nil {
dst.Spec.Image.ComputeGallery = restored.Spec.Image.ComputeGallery
}
Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha3/azuremachinetemplate_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ func (src *AzureMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Template.Spec.Image.SharedGallery.SKU = restored.Spec.Template.Spec.Image.SharedGallery.SKU
}

if restored.Spec.Template.Spec.NetworkInterfaces != nil {
dst.Spec.Template.Spec.NetworkInterfaces = restored.Spec.Template.Spec.NetworkInterfaces
}
if dst.Spec.Template.Spec.Image != nil && restored.Spec.Template.Spec.Image.ComputeGallery != nil {
dst.Spec.Template.Spec.Image.ComputeGallery = restored.Spec.Template.Spec.Image.ComputeGallery
}
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha3/zz_generated.conversion.go

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

14 changes: 13 additions & 1 deletion api/v1alpha4/azuremachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ func (src *AzureMachine) ConvertTo(dstRaw conversion.Hub) error {
return err
}


if restored.Spec.NetworkInterfaces != nil {
dst.Spec.NetworkInterfaces = restored.Spec.NetworkInterfaces
}

if restored.Spec.Image != nil && restored.Spec.Image.ComputeGallery != nil {
dst.Spec.Image.ComputeGallery = restored.Spec.Image.ComputeGallery
}

return nil
}

Expand All @@ -50,6 +54,10 @@ func (dst *AzureMachine) ConvertFrom(srcRaw conversion.Hub) error {
return err
}

if err := utilconversion.MarshalData(src, dst); err != nil {
return err
}

// Preserve Hub data on down-conversion.
return utilconversion.MarshalData(src, dst)
}
Expand All @@ -66,6 +74,10 @@ func (dst *AzureMachineList) ConvertFrom(srcRaw conversion.Hub) error {
return Convert_v1beta1_AzureMachineList_To_v1alpha4_AzureMachineList(src, dst, nil)
}

func Convert_v1beta1_AzureMachineSpec_To_v1alpha4_AzureMachineSpec(in *v1beta1.AzureMachineSpec, out *AzureMachineSpec, s apiconversion.Scope) error {
return autoConvert_v1beta1_AzureMachineSpec_To_v1alpha4_AzureMachineSpec(in, out, s)
}

func Convert_v1beta1_AzureMarketplaceImage_To_v1alpha4_AzureMarketplaceImage(in *v1beta1.AzureMarketplaceImage, out *AzureMarketplaceImage, s apiconversion.Scope) error {
out.Offer = in.ImagePlan.Offer
out.Publisher = in.ImagePlan.Publisher
Expand Down
9 changes: 7 additions & 2 deletions api/v1alpha4/azuremachinetemplate_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ import (
// ConvertTo converts this AzureMachineTemplate to the Hub version (v1beta1).
func (src *AzureMachineTemplate) ConvertTo(dstRaw conversion.Hub) error {
dst := dstRaw.(*infrav1beta1.AzureMachineTemplate)
if err := Convert_v1alpha4_AzureMachineTemplate_To_v1beta1_AzureMachineTemplate(src, dst, nil); err != nil {

if err := autoConvert_v1alpha4_AzureMachineTemplate_To_v1beta1_AzureMachineTemplate(src, dst, nil); err != nil {
return err
}

// Restore missing fields from annotations
restored := &infrav1beta1.AzureMachineTemplate{}
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
return err
}


if restored.Spec.Template.Spec.NetworkInterfaces != nil {
dst.Spec.Template.Spec.NetworkInterfaces = restored.Spec.Template.Spec.NetworkInterfaces
}

if dst.Spec.Template.Spec.Image != nil && restored.Spec.Template.Spec.Image.ComputeGallery != nil {
dst.Spec.Template.Spec.Image.ComputeGallery = restored.Spec.Template.Spec.Image.ComputeGallery
}
Expand Down
16 changes: 6 additions & 10 deletions api/v1alpha4/zz_generated.conversion.go

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

2 changes: 2 additions & 0 deletions api/v1beta1/azuremachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ type AzureMachineSpec struct {
// SubnetName selects the Subnet where the VM will be placed
// +optional
SubnetName string `json:"subnetName,omitempty"`

NetworkInterfaces []AzureNetworkInterface `json:"networkInterfaces,omitempty"`
}

// SpotVMOptions defines the options relevant to running the Machine on Spot VMs.
Expand Down
11 changes: 11 additions & 0 deletions api/v1beta1/azuremachine_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,20 @@ func ValidateAzureMachineSpec(spec AzureMachineSpec) field.ErrorList {
allErrs = append(allErrs, errs...)
}

if errs := ValidateNetwork(spec.SubnetName, spec.NetworkInterfaces, field.NewPath("networkInterfaces")); len(errs) > 0 {
allErrs = append(allErrs, errs...)
}

return allErrs
}

func ValidateNetwork(subnetName string, networkInterfaces []AzureNetworkInterface, fldPath *field.Path) field.ErrorList {
if (networkInterfaces != nil) && len(networkInterfaces) > 0 && subnetName != "" {
return field.ErrorList{field.Invalid(fldPath, networkInterfaces, "cannot set both NetworkInterfaces and machine SubnetName")}
}
return field.ErrorList{}
}

// ValidateSSHKey validates an SSHKey.
func ValidateSSHKey(sshKey string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
Expand Down
14 changes: 14 additions & 0 deletions api/v1beta1/azuremachine_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,20 @@ func (m *AzureMachine) ValidateUpdate(oldRaw runtime.Object) error {
)
}

if !reflect.DeepEqual(m.Spec.SubnetName, old.Spec.SubnetName) {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "subnetName"),
m.Spec.SecurityProfile, "field is immutable"),
)
}

if !reflect.DeepEqual(m.Spec.NetworkInterfaces, old.Spec.NetworkInterfaces) {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "networkInterfaces"),
m.Spec.SecurityProfile, "field is immutable"),
)
}

if len(allErrs) == 0 {
return nil
}
Expand Down
82 changes: 82 additions & 0 deletions api/v1beta1/azuremachine_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ func TestAzureMachine_ValidateCreate(t *testing.T) {
machine: createMachineWithOsDiskCacheType("invalid_cache_type"),
wantErr: true,
},
{
name: "azuremachine with invalid network configuration",
machine: createrMachineWithNetworkConfig("subnet", []AzureNetworkInterface{{SubnetName: "subnet1"}}),
wantErr: true,
},
{
name: "azuremachine with valid legacy network configuration",
machine: createrMachineWithNetworkConfig("subnet", []AzureNetworkInterface{}),
wantErr: false,
},
{
name: "azuremachine with valid network configuration",
machine: createrMachineWithNetworkConfig("", []AzureNetworkInterface{{SubnetName: "subnet"}}),
wantErr: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -509,6 +524,62 @@ func TestAzureMachine_ValidateUpdate(t *testing.T) {
},
wantErr: false,
},
{
name: "invalidTest: azuremachine.spec.subnetName is immutable",
oldMachine: &AzureMachine{
Spec: AzureMachineSpec{
SubnetName: "subnet1",
},
},
newMachine: &AzureMachine{
Spec: AzureMachineSpec{
SubnetName: "subnet2",
},
},
wantErr: true,
},
{
name: "invalidTest: azuremachine.spec.subnetName is immutable",
oldMachine: &AzureMachine{
Spec: AzureMachineSpec{
SubnetName: "subnet1",
},
},
newMachine: &AzureMachine{
Spec: AzureMachineSpec{
SubnetName: "subnet2",
},
},
wantErr: true,
},
{
name: "validTest: azuremachine.spec.networkInterfaces is immutable",
oldMachine: &AzureMachine{
Spec: AzureMachineSpec{
NetworkInterfaces: []AzureNetworkInterface{{SubnetName: "subnet"}},
},
},
newMachine: &AzureMachine{
Spec: AzureMachineSpec{
NetworkInterfaces: []AzureNetworkInterface{{SubnetName: "subnet"}},
},
},
wantErr: false,
},
{
name: "invalidtest: azuremachine.spec.networkInterfaces is immutable",
oldMachine: &AzureMachine{
Spec: AzureMachineSpec{
NetworkInterfaces: []AzureNetworkInterface{{SubnetName: "subnet1"}},
},
},
newMachine: &AzureMachine{
Spec: AzureMachineSpec{
NetworkInterfaces: []AzureNetworkInterface{{SubnetName: "subnet2"}},
},
},
wantErr: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -550,6 +621,17 @@ func TestAzureMachine_Default(t *testing.T) {
}
}

func createrMachineWithNetworkConfig(subnetName string, interfaces []AzureNetworkInterface) *AzureMachine {
return &AzureMachine{
Spec: AzureMachineSpec{
SubnetName: subnetName,
NetworkInterfaces: interfaces,
OSDisk: validOSDisk,
SSHPublicKey: validSSHPublicKey,
},
}
}

func createMachineWithSharedImage(subscriptionID, resourceGroup, name, gallery, version string) *AzureMachine {
image := &Image{
SharedGallery: &AzureSharedGalleryImage{
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/azuremachinetemplate_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func (r *AzureMachineTemplate) ValidateCreate() error {
)
}

if (r.Spec.Template.Spec.NetworkInterfaces != nil) && len(r.Spec.Template.Spec.NetworkInterfaces) > 0 && r.Spec.Template.Spec.SubnetName != "" {
allErrs = append(allErrs, field.Invalid(field.NewPath("AzureMachineTemplate", "spec", "template", "spec", "networkInterfaces"), r.Spec.Template.Spec.NetworkInterfaces, "cannot set both NetworkInterfaces and machine SubnetName"))
}

if len(allErrs) == 0 {
return nil
}
Expand Down
16 changes: 16 additions & 0 deletions api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,22 @@ type SubnetSpec struct {
SubnetClassSpec `json:",inline"`
}

// Network Interfaces to attach to each VM
// +optional
type AzureNetworkInterface struct {
SubnetName string `json:"subnetName,omitempty"`
IPConfigs []AzureIPConfig `json:"ipConfigs,omitempty"`
AcceleratedNetworking *bool `json:"acceleratedNetworking,omitempty"`
ID string `json:"id,omitempty"`
}

// IP Configuration defines options to confiure a network interface.
type AzureIPConfig struct {
PrivateIP string `json:"privateIP,omitempty"`
PublicIP bool `json:"publicIP,omitempty"`
PublicIPAddress string `json:"publicIPAddress,omitempty"`
}

// GetControlPlaneSubnet returns the cluster control plane subnet.
func (n *NetworkSpec) GetControlPlaneSubnet() (SubnetSpec, error) {
for _, sn := range n.Subnets {
Expand Down
47 changes: 47 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

Loading

0 comments on commit 9ab3955

Please sign in to comment.