Skip to content

Commit

Permalink
Check support for avaialibilty zones in region
Browse files Browse the repository at this point in the history
Issue: #751
  • Loading branch information
mjura committed Jan 22, 2025
1 parent c3cc14f commit 60434b2
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ MOCKGEN_VER := v0.4.0
MOCKGEN_BIN := mockgen
MOCKGEN := $(BIN_DIR)/$(MOCKGEN_BIN)-$(MOCKGEN_VER)

GINKGO_VER := v2.22.0
GINKGO_VER := v2.22.2
GINKGO_BIN := ginkgo
GINKGO := $(BIN_DIR)/$(GINKGO_BIN)-$(GINKGO_VER)

Expand Down
1 change: 1 addition & 0 deletions controller/aks-cluster-config-handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type azureClients struct {
resourceGroupsClient services.ResourceGroupsClientInterface
agentPoolsClient services.AgentPoolsClientInterface
workplacesClient services.WorkplacesClientInterface
subscriptionsClient services.SubscriptionsClientInterface
}

func Register(
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0
github.com/Azure/go-autorest/autorest v0.11.29
github.com/drone/envsubst/v2 v2.0.0-20210730161058-179042472c46
github.com/onsi/ginkgo/v2 v2.22.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armope
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights v1.2.0/go.mod h1:A4nzEXwVd5pAyneR6KOvUAo72svUc5rmCzRHhAbP6lA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 h1:wxQx2Bt4xzPIKvW59WQf1tJNx/ZZKPfN+EhPX3Z6CYY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0/go.mod h1:TpiwjwnW/khS0LKs4vW5UmmT9OWcxaveS8U7+tlknzo=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
Expand Down
62 changes: 62 additions & 0 deletions pkg/aks/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"context"
"crypto/sha256"
"fmt"
"log"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions"
"github.com/rancher/aks-operator/pkg/aks/services"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -175,3 +177,63 @@ func generateUniqueLogWorkspace(workspaceName string) string {
shaString := fmt.Sprintf("%x", hexHash)
return fmt.Sprintf("%s-%s", s, shaString[0:16])
}

var azRegionSupport = map[string]bool{
"australiaeast": true,
"brazilsouth": true,
"canadacentral": true,
"centralindia": true,
"centralus": true,
"eastasia": true,
"eastus": true,
"eastus2": true,
"eastus2euap": true,
"francecentral": true,
"germanywestcentral": true,
"israelcentral": true,
"italynorth": true,
"japaneast": true,
"koreacentral": true,
"mexicocentral": true,
"newzealandnorth": true,
"northeurope": true,
"norwayeast": true,
"polandcentral": true,
"qatarcentral": true,
"southafricanorth": true,
"southcentralus": true,
"southeastasia": true,
"spaincentral": true,
"swedencentral": true,
"switzerlandnorth": true,
"uaenorth": true,
"uksouth": true,
"westeurope": true,
"westus2": true,
"westus3": true,
}

func CheckAvailabilityZonesSupport(location string) bool {
return azRegionSupport[location]
}

func CheckAvailabilityZonesSupportAPI(ctx context.Context, client services.SubscriptionsClientInterface, subscription string, location string) bool {
pager := client.NewListLocationsPager(subscription, &armsubscriptions.ClientListLocationsOptions{IncludeExtendedLocations: nil})
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
log.Fatalf("failed to advance page: %v", err)
}
for _, v := range page.Value {
if v.Name != nil && *v.Name == location {
if len(v.AvailabilityZoneMappings) > 0 {
logrus.Debugf("Region %s supports availability zones : ", location)
return true
}

}

Check failure on line 234 in pkg/aks/check.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary trailing newline (whitespace)
}
}
logrus.Debugf("Region %s does not support availability zones", location)
return false
}
7 changes: 7 additions & 0 deletions pkg/aks/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ func createManagedCluster(ctx context.Context, cred *Credentials, workplacesClie
agentProfile.OrchestratorVersion = np.OrchestratorVersion
}
if np.AvailabilityZones != nil && len(*np.AvailabilityZones) > 0 {
if !CheckAvailabilityZonesSupport(spec.ResourceLocation) {
return nil, fmt.Errorf("availability zones are not supported in region %s", spec.ResourceLocation)
}
agentProfile.AvailabilityZones = utils.ConvertToSliceOfPointers(np.AvailabilityZones)
}

Expand Down Expand Up @@ -306,6 +309,10 @@ func createManagedCluster(ctx context.Context, cred *Credentials, workplacesClie
// CreateOrUpdateAgentPool creates a new pool(s) in AKS. If one already exists it updates the upstream node pool with
// any provided updates.
func CreateOrUpdateAgentPool(ctx context.Context, agentPoolClient services.AgentPoolsClientInterface, spec *aksv1.AKSClusterConfigSpec, np *aksv1.AKSNodePool) error {
if np.AvailabilityZones != nil && len(*np.AvailabilityZones) > 0 && !CheckAvailabilityZonesSupport(spec.ResourceLocation) {
return fmt.Errorf("availability zones are not supported in region %s", spec.ResourceLocation)
}

agentProfile := &armcontainerservice.ManagedClusterAgentPoolProfileProperties{
Count: np.Count,
MaxPods: np.MaxPods,
Expand Down
8 changes: 8 additions & 0 deletions pkg/aks/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ var _ = Describe("newManagedCluster", func() {
},
}, nil)
clusterSpec.ResourceLocation = "chinaeast"
clusterSpec.NodePools[0].AvailabilityZones = nil
managedCluster, err := createManagedCluster(ctx, cred, workplacesClientMock, clusterSpec, "test-phase")
Expect(err).ToNot(HaveOccurred())

Expand Down Expand Up @@ -436,6 +437,13 @@ var _ = Describe("newManagedCluster", func() {

Expect(managedCluster.Identity).To(BeNil())
})

It("should fail create managed cluster with az in region which doesn't support it", func() {
clusterSpec.ResourceLocation = "westus"
clusterSpec.NodePools[0].AvailabilityZones = to.Ptr([]string{"1", "2", "3"})
_, err := createManagedCluster(ctx, cred, workplacesClientMock, clusterSpec, "test-phase")
Expect(err).To(HaveOccurred())
})
})

var _ = Describe("CreateCluster", func() {
Expand Down
1 change: 1 addition & 0 deletions pkg/aks/services/mock_services/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ package mock_services
//go:generate ../../../../bin/mockgen -destination agentpools_mock.go -package mock_services -source ../agentpools.go AgentPoolsClientInterface
//go:generate ../../../../bin/mockgen -destination groups_mock.go -package mock_services -source ../groups.go ResourceGroupsClientInterface
//go:generate ../../../../bin/mockgen -destination managedclusters_mock.go -package mock_services -source ../managedclusters.go ManagedClustersClientInterface
//go:generate ../../../../bin/mockgen -destination subscriptions_mock.go -package mock_services -source ../subscriptions.go SubscriptionsClientInterface
//go:generate ../../../../bin/mockgen -destination workplaces_mock.go -package mock_services -source ../workplaces.go WorkplacesClientInterface
55 changes: 55 additions & 0 deletions pkg/aks/services/mock_services/subscriptions_mock.go

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

38 changes: 38 additions & 0 deletions pkg/aks/services/subscriptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package services

import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions"
)

type SubscriptionsClientInterface interface {
NewListLocationsPager(subscriptionID string, options *armsubscriptions.ClientListLocationsOptions) *runtime.Pager[armsubscriptions.ClientListLocationsResponse]
}

type subscriptionClient struct {
subscriptionClient *armsubscriptions.Client
}

func NewSubscriptionClient(credential *azidentity.ClientSecretCredential, cloud cloud.Configuration) (*subscriptionClient, error) {
options := arm.ClientOptions{
ClientOptions: azcore.ClientOptions{
Cloud: cloud,
},
}
clientFactory, err := armsubscriptions.NewClientFactory(credential, &options)
if err != nil {
return nil, err
}

return &subscriptionClient{
subscriptionClient: clientFactory.NewClient(),
}, nil
}

func (cl *subscriptionClient) NewListLocationsPager(subscriptionID string, options *armsubscriptions.ClientListLocationsOptions) *runtime.Pager[armsubscriptions.ClientListLocationsResponse] {
return cl.subscriptionClient.NewListLocationsPager(subscriptionID, options)
}

0 comments on commit 60434b2

Please sign in to comment.