From 53b1f765a25efba2f9e675d7648ea7439a5a2670 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Thu, 20 Apr 2023 18:07:37 -0400 Subject: [PATCH] feat(AzureEnvironments): use upstream func for validation remove hard-coded maps for Azure environments and call EnvironmentFromName function from go-autorest/azure library to leverage upstream provider to validate Azure Environments also enables initial ability to specify custom endpoints for AzureStackCloud by using the Environment 'AzureStackCloud' and specifying AZURE_ENVIRONMENT_FILEPATH and providing an AzureEnvironment json file Closes Issue #3162 Signed-off-by: Jeff Davis --- providers/config_default.yaml | 2 +- .../v1.6.3/infrastructure-components.yaml | 6 +-- tkg/azure/client.go | 28 +++-------- tkg/azure/client_test.go | 46 +++++++++++++++++++ tkg/azure/testdata/test_environment_1.json | 36 +++++++++++++++ 5 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 tkg/azure/testdata/test_environment_1.json diff --git a/providers/config_default.yaml b/providers/config_default.yaml index 31384c0d7d..bead64f0a4 100644 --- a/providers/config_default.yaml +++ b/providers/config_default.yaml @@ -361,7 +361,7 @@ CONTROL_PLANE_NODE_LABELS: #! Azure account configurations #! The Azure cloud to deploy to, supported clouds are : -#! AzurePublicCloud, AzureChinaCloud, AzureGermanCloud, AzureUSGovernmentCloud +#! AzurePublicCloud, AzureChinaCloud, AzureGermanCloud, AzureUSGovernmentCloud, AzureStackCloud AZURE_ENVIRONMENT: "AzurePublicCloud" #! The tenant ID is the ID of the AAD directory in which the app for Tanzu Kubernetes Grid is created #! A Tenant is representative of an organization within Azure Active Directory. diff --git a/providers/infrastructure-azure/v1.6.3/infrastructure-components.yaml b/providers/infrastructure-azure/v1.6.3/infrastructure-components.yaml index 8cf8cc8e04..794d9f2216 100644 --- a/providers/infrastructure-azure/v1.6.3/infrastructure-components.yaml +++ b/providers/infrastructure-azure/v1.6.3/infrastructure-components.yaml @@ -780,7 +780,7 @@ spec: description: AdditionalTags is an optional set of tags to add to Azure resources managed by the Azure provider, in addition to the ones added by default. type: object azureEnvironment: - description: 'AzureEnvironment is the name of the AzureCloud to be used. The default value that would be used by most users is "AzurePublicCloud", other values are: - ChinaCloud: "AzureChinaCloud" - GermanCloud: "AzureGermanCloud" - PublicCloud: "AzurePublicCloud" - USGovernmentCloud: "AzureUSGovernmentCloud"' + description: 'AzureEnvironment is the name of the AzureCloud to be used. The default value that would be used by most users is "AzurePublicCloud", other values are: - ChinaCloud: "AzureChinaCloud" - GermanCloud: "AzureGermanCloud" - PublicCloud: "AzurePublicCloud" - USGovernmentCloud: "AzureUSGovernmentCloud" - StackCloud: "AzureStackCloud" - StackCloud: "AzureStackCloud"' type: string bastionSpec: description: BastionSpec encapsulates all things related to the Bastions in the cluster. @@ -1444,7 +1444,7 @@ spec: description: AdditionalTags is an optional set of tags to add to Azure resources managed by the Azure provider, in addition to the ones added by default. type: object azureEnvironment: - description: 'AzureEnvironment is the name of the AzureCloud to be used. The default value that would be used by most users is "AzurePublicCloud", other values are: - ChinaCloud: "AzureChinaCloud" - GermanCloud: "AzureGermanCloud" - PublicCloud: "AzurePublicCloud" - USGovernmentCloud: "AzureUSGovernmentCloud"' + description: 'AzureEnvironment is the name of the AzureCloud to be used. The default value that would be used by most users is "AzurePublicCloud", other values are: - ChinaCloud: "AzureChinaCloud" - GermanCloud: "AzureGermanCloud" - PublicCloud: "AzurePublicCloud" - USGovernmentCloud: "AzureUSGovernmentCloud" - StackCloud: "AzureStackCloud" - StackCloud: "AzureStackCloud"' type: string bastionSpec: description: BastionSpec encapsulates all things related to the Bastions in the cluster. @@ -2303,7 +2303,7 @@ spec: description: AdditionalTags is an optional set of tags to add to Azure resources managed by the Azure provider, in addition to the ones added by default. type: object azureEnvironment: - description: 'AzureEnvironment is the name of the AzureCloud to be used. The default value that would be used by most users is "AzurePublicCloud", other values are: - ChinaCloud: "AzureChinaCloud" - GermanCloud: "AzureGermanCloud" - PublicCloud: "AzurePublicCloud" - USGovernmentCloud: "AzureUSGovernmentCloud"' + description: 'AzureEnvironment is the name of the AzureCloud to be used. The default value that would be used by most users is "AzurePublicCloud", other values are: - ChinaCloud: "AzureChinaCloud" - GermanCloud: "AzureGermanCloud" - PublicCloud: "AzurePublicCloud" - USGovernmentCloud: "AzureUSGovernmentCloud" - StackCloud: "AzureStackCloud" - StackCloud: "AzureStackCloud"' type: string bastionSpec: description: BastionSpec encapsulates all things related to the Bastions in the cluster. diff --git a/tkg/azure/client.go b/tkg/azure/client.go index 77799c8e50..5699e8ed83 100644 --- a/tkg/azure/client.go +++ b/tkg/azure/client.go @@ -31,14 +31,8 @@ const ( ) const ( - // ChinaCloud defines China cloud - ChinaCloud = "AzureChinaCloud" - // GermanCloud defines German cloud - GermanCloud = "AzureGermanCloud" // PublicCloud defines Public cloud PublicCloud = "AzurePublicCloud" - // USGovernmentCloud defines US Government cloud - USGovernmentCloud = "AzureUSGovernmentCloud" ) // Supported Azure VM family types @@ -108,22 +102,14 @@ func New(creds *Credentials) (Client, error) { } func setActiveDirectoryEndpoint(config *auth.ClientCredentialsConfig, azureCloud string) error { - switch azureCloud { - case USGovernmentCloud: - config.Resource = azure.USGovernmentCloud.ResourceManagerEndpoint - config.AADEndpoint = azure.USGovernmentCloud.ActiveDirectoryEndpoint - case ChinaCloud: - config.Resource = azure.ChinaCloud.ResourceManagerEndpoint - config.AADEndpoint = azure.ChinaCloud.ActiveDirectoryEndpoint - case GermanCloud: - config.Resource = azure.GermanCloud.ResourceManagerEndpoint - config.AADEndpoint = azure.GermanCloud.ActiveDirectoryEndpoint - case PublicCloud: - config.Resource = azure.PublicCloud.ResourceManagerEndpoint - config.AADEndpoint = azure.PublicCloud.ActiveDirectoryEndpoint - default: - return errors.Errorf("%q is not a supported cloud in Azure. Supported clouds are AzurePublicCloud, AzureUSGovernmentCloud, AzureGermanCloud, AzureChinaCloud", azureCloud) + environment, err := azure.EnvironmentFromName(azureCloud) + if err != nil { + return err } + + config.Resource = environment.ResourceManagerEndpoint + config.AADEndpoint = environment.ActiveDirectoryEndpoint + return nil } diff --git a/tkg/azure/client_test.go b/tkg/azure/client_test.go index 681eac82e5..10edf71806 100644 --- a/tkg/azure/client_test.go +++ b/tkg/azure/client_test.go @@ -7,6 +7,10 @@ package azure import ( "context" "errors" + "os" + "path" + "path/filepath" + "runtime" "testing" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute" @@ -170,6 +174,48 @@ var _ = Describe("Azure client", func() { }) }) + Context("with azureCloud set to 'AzureStackCloud'", func() { + Context("with AZURE_ENVIRONMENT_FILEPATH unset", func() { + It("should return error", func() { + config := &auth.ClientCredentialsConfig{} + err := setActiveDirectoryEndpoint(config, "AzureStackCloud") + Expect(err).To(HaveOccurred()) + }) + }) + + Context("with AZURE_ENVIRONMENT_FILEPATH set", func() { + It("should not return error with valid file", func() { + _, currentFile, _, _ := runtime.Caller(0) + os.Setenv("AZURE_ENVIRONMENT_FILEPATH", filepath.Join(path.Dir(currentFile), "testdata", "test_environment_1.json")) + + config := &auth.ClientCredentialsConfig{} + err := setActiveDirectoryEndpoint(config, "AzureStackCloud") + Expect(err).ToNot(HaveOccurred()) + + Expect(config.Resource).To(Equal("--resource-management-endpoint--")) + Expect(config.AADEndpoint).To(Equal("--active-directory-endpoint--")) + }) + + It("should throw error with missing file", func() { + _, currentFile, _, _ := runtime.Caller(0) + os.Setenv("AZURE_ENVIRONMENT_FILEPATH", filepath.Join(path.Dir(currentFile), "testdata", "test_environment_2.json")) + + config := &auth.ClientCredentialsConfig{} + err := setActiveDirectoryEndpoint(config, "AzureStackCloud") + Expect(err).To(HaveOccurred()) + }) + + It("should throw error with invalid file", func() { + _, currentFile, _, _ := runtime.Caller(0) + os.Setenv("AZURE_ENVIRONMENT_FILEPATH", filepath.Join(path.Dir(currentFile), "mocks", "azure_mock.go")) + + config := &auth.ClientCredentialsConfig{} + err := setActiveDirectoryEndpoint(config, "AzureStackCloud") + Expect(err).To(HaveOccurred()) + }) + }) + }) + Context("with azureCloud set to 'AzurePublicCloud'", func() { It("should not return error", func() { config := &auth.ClientCredentialsConfig{} diff --git a/tkg/azure/testdata/test_environment_1.json b/tkg/azure/testdata/test_environment_1.json new file mode 100644 index 0000000000..1a41f90c05 --- /dev/null +++ b/tkg/azure/testdata/test_environment_1.json @@ -0,0 +1,36 @@ +{ + "name": "--unit-test--", + "managementPortalURL": "--management-portal-url", + "publishSettingsURL": "--publish-settings-url--", + "serviceManagementEndpoint": "--service-management-endpoint--", + "resourceManagerEndpoint": "--resource-management-endpoint--", + "activeDirectoryEndpoint": "--active-directory-endpoint--", + "galleryEndpoint": "--gallery-endpoint--", + "keyVaultEndpoint": "--key-vault--endpoint--", + "managedHSMEndpoint": "--managed-hsm-endpoint--", + "graphEndpoint": "--graph-endpoint--", + "storageEndpointSuffix": "--storage-endpoint-suffix--", + "cosmosDBDNSSuffix": "--cosmos-db-dns-suffix--", + "mariaDBDNSSuffix": "--maria-db-dns-suffix--", + "mySqlDatabaseDNSSuffix": "--mysql-database-dns-suffix--", + "postgresqlDatabaseDNSSuffix": "--postgresql-database-dns-suffix--", + "sqlDatabaseDNSSuffix": "--sql-database-dns-suffix--", + "trafficManagerDNSSuffix": "--traffic-manager-dns-suffix--", + "keyVaultDNSSuffix": "--key-vault-dns-suffix--", + "managedHSMDNSSuffix": "--managed-hsm-dns-suffix--", + "serviceBusEndpointSuffix": "--service-bus-endpoint-suffix--", + "serviceManagementVMDNSSuffix": "--asm-vm-dns-suffix--", + "resourceManagerVMDNSSuffix": "--arm-vm-dns-suffix--", + "containerRegistryDNSSuffix": "--container-registry-dns-suffix--", + "tokenAudience": "--token-audience", + "resourceIdentifiers": { + "batch": "--batch-resource-id--", + "datalake": "--datalake-resource-id--", + "graph": "--graph-resource-id--", + "keyVault": "--keyvault-resource-id--", + "operationalInsights": "--operational-insights-resource-id--", + "ossRDBMS": "--oss-rdbms-resource-id--", + "cosmosDB": "--cosmosdb-resource-id--", + "managedHSM": "--managed-hsm-resource-id--" + } +}