Skip to content

Commit

Permalink
add subnetName support to ammp
Browse files Browse the repository at this point in the history
  • Loading branch information
LochanRn committed Mar 20, 2023
1 parent 632516c commit 682789e
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 1 deletion.
1 change: 1 addition & 0 deletions api/v1alpha3/azuremanagedmachinepool_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func (src *AzureManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
if restored.Spec.KubeletConfig != nil {
dst.Spec.KubeletConfig = restored.Spec.KubeletConfig
}
dst.Spec.SubnetName = restored.Spec.SubnetName

dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates
dst.Status.Conditions = restored.Status.Conditions
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.

1 change: 1 addition & 0 deletions api/v1alpha4/azuremanagedmachinepool_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func (src *AzureManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
if restored.Spec.KubeletConfig != nil {
dst.Spec.KubeletConfig = restored.Spec.KubeletConfig
}
dst.Spec.SubnetName = restored.Spec.SubnetName

dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates
dst.Status.Conditions = restored.Status.Conditions
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha4/zz_generated.conversion.go

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

3 changes: 3 additions & 0 deletions api/v1beta1/azuremanagedmachinepool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,9 @@ type AzureManagedMachinePoolSpec struct {
// LinuxOSConfig specifies the custom Linux OS settings and configurations.
// +optional
LinuxOSConfig *LinuxOSConfig `json:"linuxOSConfig,omitempty"`
// SubnetName specifies the Subnet where the MachinePool will be placed
// +optional
SubnetName *string `json:"subnetName,omitempty"`
}

// ManagedMachinePoolScaling specifies scaling options.
Expand Down
21 changes: 21 additions & 0 deletions api/v1beta1/azuremanagedmachinepool_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"strconv"
"strings"

"github.com/Azure/go-autorest/autorest/to"
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -80,6 +81,7 @@ func (m *AzureManagedMachinePool) ValidateCreate(client client.Client) error {
m.validateEnableNodePublicIP,
m.validateKubeletConfig,
m.validateLinuxOSConfig,
m.validateSubnetName,
}

var errs []error
Expand Down Expand Up @@ -133,6 +135,13 @@ func (m *AzureManagedMachinePool) ValidateUpdate(oldRaw runtime.Object, client c
allErrs = append(allErrs, err)
}

if err := webhookutils.ValidateImmutable(
field.NewPath("Spec", "SubnetName"),
old.Spec.SubnetName,
m.Spec.SubnetName); err != nil && old.Spec.SubnetName != nil {
allErrs = append(allErrs, err)
}

// custom headers are immutable
oldCustomHeaders := maps.FilterByKeyPrefix(old.ObjectMeta.Annotations, CustomHeaderPrefix)
newCustomHeaders := maps.FilterByKeyPrefix(m.ObjectMeta.Annotations, CustomHeaderPrefix)
Expand Down Expand Up @@ -356,6 +365,18 @@ func (m *AzureManagedMachinePool) validateEnableNodePublicIP() error {
return nil
}

func (m *AzureManagedMachinePool) validateSubnetName() error {
if m.Spec.SubnetName != nil {
subnetRegex := "^[a-zA-Z0-9][a-zA-Z0-9-]{0,78}[a-zA-Z0-9]$"
regex := regexp.MustCompile(subnetRegex)
if success := regex.MatchString(to.String(m.Spec.SubnetName)); !success {
return field.Invalid(field.NewPath("Spec", "SubnetName"), m.Spec.SubnetName,
fmt.Sprintf("name of subnet doesn't match regex %s", subnetRegex))
}
}
return nil
}

// validateKubeletConfig enforces the AKS API configuration for KubeletConfig.
// See: https://learn.microsoft.com/en-us/azure/aks/custom-node-configuration.
func (m *AzureManagedMachinePool) validateKubeletConfig() error {
Expand Down
130 changes: 130 additions & 0 deletions api/v1beta1/azuremanagedmachinepool_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"testing"

"github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2022-03-01/containerservice"
"github.com/Azure/go-autorest/autorest/to"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -535,6 +536,48 @@ func TestAzureManagedMachinePoolUpdatingWebhook(t *testing.T) {
},
wantErr: true,
},
{
name: "Can't update SubnetName with error",
new: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("my-subnet"),
},
},
old: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("my-subnet-1"),
},
},
wantErr: true,
},
{
name: "Can update SubnetName if subnetName is empty",
new: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("my-subnet"),
},
},
old: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: nil,
},
},
wantErr: false,
},
{
name: "Can't update SubnetName without error",
new: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("my-subnet"),
},
},
old: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("my-subnet"),
},
},
wantErr: false,
},
}
var client client.Client
for _, tc := range tests {
Expand Down Expand Up @@ -593,6 +636,93 @@ func TestAzureManagedMachinePool_ValidateCreate(t *testing.T) {
wantErr: true,
errorLen: 1,
},
{
name: "invalid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("1+subnet"),
},
},
wantErr: true,
errorLen: 1,
},
{
name: "invalid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("1"),
},
},
wantErr: true,
errorLen: 1,
},
{
name: "invalid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("-a_b-c"),
},
},
wantErr: true,
errorLen: 1,
},
{
name: "invalid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("E-a_b-c"),
},
},
wantErr: true,
errorLen: 1,
},
{
name: "invalid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("-_-_"),
},
},
wantErr: true,
errorLen: 1,
},
{
name: "invalid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("abc@#$"),
},
},
wantErr: true,
errorLen: 1,
},
{
name: "valid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("1abc"),
},
},
wantErr: false,
},
{
name: "valid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("1-a-b-c"),
},
},
wantErr: false,
},
{
name: "valid subnetname",
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
SubnetName: to.StringPtr("my-subnet"),
},
},
wantErr: false,
},
{
name: "too few MaxPods",
ammp: &AzureManagedMachinePool{
Expand Down
5 changes: 5 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.

10 changes: 9 additions & 1 deletion azure/scope/managedmachinepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"strings"

"github.com/Azure/go-autorest/autorest/to"
"github.com/pkg/errors"
"k8s.io/utils/pointer"
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
Expand Down Expand Up @@ -134,6 +135,13 @@ func (s *ManagedMachinePoolScope) Name() string {
return s.InfraMachinePool.Name
}

// SetSubnetName updates AzureManagedMachinePool.SubnetName if AzureManagedMachinePool.SubnetName is empty with s.ControlPlane.Spec.VirtualNetwork.Subnet.Name.
func (s *ManagedMachinePoolScope) SetSubnetName() {
if s.ControlPlane.Spec.VirtualNetwork.Name != "" && s.InfraMachinePool.Spec.SubnetName == nil {
s.InfraMachinePool.Spec.SubnetName = to.StringPtr(s.ControlPlane.Spec.VirtualNetwork.Subnet.Name)
}
}

// AgentPoolSpec returns an azure.ResourceSpecGetter for currently reconciled AzureManagedMachinePool.
func (s *ManagedMachinePoolScope) AgentPoolSpec() azure.ResourceSpecGetter {
return buildAgentPoolSpec(s.ControlPlane, s.MachinePool, s.InfraMachinePool, s.AgentPoolAnnotations())
Expand Down Expand Up @@ -166,7 +174,7 @@ func buildAgentPoolSpec(managedControlPlane *infrav1.AzureManagedControlPlane,
managedControlPlane.Spec.SubscriptionID,
managedControlPlane.Spec.VirtualNetwork.ResourceGroup,
managedControlPlane.Spec.VirtualNetwork.Name,
managedControlPlane.Spec.VirtualNetwork.Subnet.Name,
to.String(managedMachinePool.Spec.SubnetName),
),
Mode: managedMachinePool.Spec.Mode,
MaxPods: managedMachinePool.Spec.MaxPods,
Expand Down
Loading

0 comments on commit 682789e

Please sign in to comment.