Skip to content

Commit

Permalink
Merge pull request #4009 from spectrocloud/support-aks-custom-dns-prefix
Browse files Browse the repository at this point in the history
Support for custom dns prefix for aks clusters
  • Loading branch information
k8s-ci-robot authored Oct 4, 2023
2 parents 0406a5b + 24c7651 commit 44cb72a
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 3 deletions.
6 changes: 6 additions & 0 deletions api/v1beta1/azuremanagedcontrolplane_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,9 @@ func (m *AzureManagedControlPlane) setDefaultOIDCIssuerProfile() {
m.Spec.OIDCIssuerProfile.Enabled = ptr.To(false)
}
}

func (m *AzureManagedControlPlane) setDefaultDNSPrefix() {
if m.Spec.DNSPrefix == nil {
m.Spec.DNSPrefix = ptr.To(m.Name)
}
}
5 changes: 5 additions & 0 deletions api/v1beta1/azuremanagedcontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@ type AzureManagedControlPlaneSpec struct {
// OIDCIssuerProfile is the OIDC issuer profile of the Managed Cluster.
// +optional
OIDCIssuerProfile *OIDCIssuerProfile `json:"oidcIssuerProfile,omitempty"`

// DNSPrefix allows the user to customize dns prefix.
// Immutable.
// +optional
DNSPrefix *string `json:"dnsPrefix,omitempty"`
}

// HTTPProxyConfig is the HTTP proxy configuration for the cluster.
Expand Down
30 changes: 30 additions & 0 deletions api/v1beta1/azuremanagedcontrolplane_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func (mw *azureManagedControlPlaneWebhook) Default(ctx context.Context, obj runt
m.setDefaultSku()
m.setDefaultAutoScalerProfile()
m.setDefaultOIDCIssuerProfile()
m.setDefaultDNSPrefix()

return nil
}
Expand Down Expand Up @@ -246,6 +247,14 @@ func (mw *azureManagedControlPlaneWebhook) ValidateUpdate(ctx context.Context, o
}
}

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

// Consider removing this once moves out of preview
// Updating outboundType after cluster creation (PREVIEW)
// https://learn.microsoft.com/en-us/azure/aks/egress-outboundtype#updating-outboundtype-after-cluster-creation-preview
Expand Down Expand Up @@ -296,6 +305,7 @@ func (m *AzureManagedControlPlane) Validate(cli client.Client) error {
m.validateAutoScalerProfile,
m.validateIdentity,
m.validateNetworkPluginMode,
m.validateDNSPrefix,
}

var errs []error
Expand All @@ -308,6 +318,26 @@ func (m *AzureManagedControlPlane) Validate(cli client.Client) error {
return kerrors.NewAggregate(errs)
}

func (m *AzureManagedControlPlane) validateDNSPrefix(_ client.Client) error {
if m.Spec.DNSPrefix == nil {
return nil
}

// Regex pattern for DNS prefix validation
// 1. Between 1 and 54 characters long: {1,54}
// 2. Alphanumerics and hyphens: [a-zA-Z0-9-]
// 3. Start and end with alphanumeric: ^[a-zA-Z0-9].*[a-zA-Z0-9]$
pattern := `^[a-zA-Z0-9][a-zA-Z0-9-]{0,52}[a-zA-Z0-9]$`
regex := regexp.MustCompile(pattern)
if regex.MatchString(ptr.Deref(m.Spec.DNSPrefix, "")) {
return nil
}
allErrs := field.ErrorList{
field.Invalid(field.NewPath("Spec", "DNSPrefix"), *m.Spec.DNSPrefix, "DNSPrefix is invalid, does not match regex: "+pattern),
}
return kerrors.NewAggregate(allErrs.ToAggregate().Errors())
}

// validateVersion validates the Kubernetes version.
func (m *AzureManagedControlPlane) validateVersion(_ client.Client) error {
if !kubeSemver.MatchString(m.Spec.Version) {
Expand Down
156 changes: 155 additions & 1 deletion api/v1beta1/azuremanagedcontrolplane_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func TestDefaultingWebhook(t *testing.T) {
g.Expect(amcp.Spec.SKU.Tier).To(Equal(FreeManagedControlPlaneTier))
g.Expect(amcp.Spec.Identity.Type).To(Equal(ManagedControlPlaneIdentityTypeSystemAssigned))
g.Expect(*amcp.Spec.OIDCIssuerProfile.Enabled).To(BeFalse())
g.Expect(amcp.Spec.DNSPrefix).ToNot(BeNil())
g.Expect(*amcp.Spec.DNSPrefix).To(Equal(amcp.Name))

t.Logf("Testing amcp defaulting webhook with baseline")
netPlug := "kubenet"
Expand All @@ -76,6 +78,7 @@ func TestDefaultingWebhook(t *testing.T) {
amcp.Spec.OIDCIssuerProfile = &OIDCIssuerProfile{
Enabled: ptr.To(true),
}
amcp.Spec.DNSPrefix = ptr.To("test-prefix")

err = mcpw.Default(context.Background(), amcp)
g.Expect(err).NotTo(HaveOccurred())
Expand All @@ -89,7 +92,8 @@ func TestDefaultingWebhook(t *testing.T) {
g.Expect(amcp.Spec.VirtualNetwork.Subnet.Name).To(Equal("fooSubnetName"))
g.Expect(amcp.Spec.SKU.Tier).To(Equal(StandardManagedControlPlaneTier))
g.Expect(*amcp.Spec.OIDCIssuerProfile.Enabled).To(BeTrue())

g.Expect(amcp.Spec.DNSPrefix).ToNot(BeNil())
g.Expect(*amcp.Spec.DNSPrefix).To(Equal("test-prefix"))
t.Logf("Testing amcp defaulting webhook with overlay")
amcp = &AzureManagedControlPlane{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -778,6 +782,76 @@ func TestAzureManagedControlPlane_ValidateCreate(t *testing.T) {
wantErr: true,
errorLen: 1,
},
{
name: "Testing inValid DNSPrefix for starting with invalid characters",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("-thisi$"),
Version: "v1.17.8",
},
},
wantErr: true,
},
{
name: "Testing inValid DNSPrefix with more then 54 characters",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("thisisaverylong$^clusternameconsistingofmorethan54characterswhichshouldbeinvalid"),
Version: "v1.17.8",
},
},
wantErr: true,
},
{
name: "Testing inValid DNSPrefix with underscore",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("no_underscore"),
Version: "v1.17.8",
},
},
wantErr: true,
},
{
name: "Testing inValid DNSPrefix with special characters",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("no-dollar$@%"),
Version: "v1.17.8",
},
},
wantErr: true,
},
{
name: "Testing Valid DNSPrefix with hyphen characters",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("hyphen-allowed"),
Version: "v1.17.8",
},
},
wantErr: false,
},
{
name: "Testing Valid DNSPrefix with hyphen characters",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("palette-test07"),
Version: "v1.17.8",
},
},
wantErr: false,
},
{
name: "Testing valid DNSPrefix ",
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("thisisavlerylongclu7l0sternam3leconsistingofmorethan54"),
Version: "v1.17.8",
},
},
wantErr: false,
},
{
name: "invalid name with microsoft",
amcp: &AzureManagedControlPlane{
Expand Down Expand Up @@ -1609,6 +1683,86 @@ func TestAzureManagedControlPlane_ValidateUpdate(t *testing.T) {
},
wantErr: false,
},
{
name: "AzureManagedControlPlane DNSPrefix is immutable error",
oldAMCP: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("capz-aks-1"),
Version: "v1.18.0",
},
},
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("capz-aks"),
Version: "v1.18.0",
},
},
wantErr: true,
},
{
name: "AzureManagedControlPlane DNSPrefix is immutable no error",
oldAMCP: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("capz-aks"),
Version: "v1.18.0",
},
},
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("capz-aks"),
Version: "v1.18.0",
},
},
wantErr: false,
},
{
name: "AzureManagedControlPlane DNSPrefix is immutable error nil -> capz-aks",
oldAMCP: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: nil,
Version: "v1.18.0",
},
},
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To("capz-aks"),
Version: "v1.18.0",
},
},
wantErr: true,
},
{
name: "AzureManagedControlPlane DNSPrefix is immutable error nil -> empty",
oldAMCP: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: nil,
Version: "v1.18.0",
},
},
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: ptr.To(""),
Version: "v1.18.0",
},
},
wantErr: true,
},
{
name: "AzureManagedControlPlane DNSPrefix is immutable no error nil -> nil",
oldAMCP: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: nil,
Version: "v1.18.0",
},
},
amcp: &AzureManagedControlPlane{
Spec: AzureManagedControlPlaneSpec{
DNSPrefix: nil,
Version: "v1.18.0",
},
},
wantErr: false,
},
}
client := mockClient{ReturnError: false}
for _, tc := range tests {
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.

1 change: 1 addition & 0 deletions azure/scope/managedcontrolplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ func (s *ManagedControlPlaneScope) ManagedClusterSpec() azure.ResourceSpecGetter
Identity: s.ControlPlane.Spec.Identity,
KubeletUserAssignedIdentity: s.ControlPlane.Spec.KubeletUserAssignedIdentity,
NetworkPluginMode: s.ControlPlane.Spec.NetworkPluginMode,
DNSPrefix: s.ControlPlane.Spec.DNSPrefix,
}

if s.ControlPlane.Spec.SSHPublicKey != nil {
Expand Down
5 changes: 4 additions & 1 deletion azure/services/managedclusters/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ type ManagedClusterSpec struct {

// OIDCIssuerProfile is the OIDC issuer profile of the Managed Cluster.
OIDCIssuerProfile *OIDCIssuerProfile

// DNSPrefix allows the user to customize dns prefix.
DNSPrefix *string
}

// HTTPProxyConfig is the HTTP proxy configuration for the cluster.
Expand Down Expand Up @@ -326,7 +329,7 @@ func (s *ManagedClusterSpec) Parameters(ctx context.Context, existing interface{
Properties: &armcontainerservice.ManagedClusterProperties{
NodeResourceGroup: &s.NodeResourceGroup,
EnableRBAC: ptr.To(true),
DNSPrefix: &s.Name,
DNSPrefix: s.DNSPrefix,
KubernetesVersion: &s.Version,

ServicePrincipalProfile: &armcontainerservice.ManagedClusterServicePrincipalProfile{
Expand Down
1 change: 0 additions & 1 deletion azure/services/managedclusters/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ func getSampleManagedCluster() armcontainerservice.ManagedCluster {
return armcontainerservice.ManagedCluster{
Properties: &armcontainerservice.ManagedClusterProperties{
KubernetesVersion: ptr.To("v1.22.0"),
DNSPrefix: ptr.To("test-managedcluster"),
AgentPoolProfiles: []*armcontainerservice.ManagedClusterAgentPoolProfile{
{
Name: ptr.To("test-agentpool-0"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ spec:
- host
- port
type: object
dnsPrefix:
description: DNSPrefix allows the user to customize dns prefix. Immutable.
type: string
dnsServiceIP:
description: DNSServiceIP is an IP address assigned to the Kubernetes
DNS service. It must be within the Kubernetes service address range
Expand Down

0 comments on commit 44cb72a

Please sign in to comment.