Skip to content

Commit 90c2c2d

Browse files
committed
Set ARMClientOptions for Azure Stack
Sets ARM Client Options when using the Azure Stack environment. Extends ARMClientOptions to accept an ARMEndpoint, which can be obtained from the authorizer interface, the same source the cloud environment. Sets the APIVersion to a hybrid cloud profile to ensure compatibility with hybrid environments.
1 parent c912d05 commit 90c2c2d

File tree

23 files changed

+52
-29
lines changed

23 files changed

+52
-29
lines changed

azure/defaults.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
2929
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
3030
"github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel"
31+
"github.com/Azure/go-autorest/autorest/azure"
3132

3233
"sigs.k8s.io/cluster-api-provider-azure/pkg/ot"
3334
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
@@ -112,6 +113,12 @@ const (
112113
CustomHeaderPrefix = "infrastructure.cluster.x-k8s.io/custom-header-"
113114
)
114115

116+
const (
117+
// StackAPIVersion is the API version profile to set for ARM clients. See:
118+
// https://learn.microsoft.com/en-us/azure-stack/user/azure-stack-profiles-azure-resource-manager-versions?view=azs-2408#overview-of-the-2020-09-01-hybrid-profile
119+
StackAPIVersionProfile = "2020-06-01"
120+
)
121+
115122
var (
116123
// LinuxBootstrapExtensionCommand is the command the VM bootstrap extension will execute to verify Linux nodes bootstrap completes successfully.
117124
LinuxBootstrapExtensionCommand = fmt.Sprintf("for i in $(seq 1 %d); do test -f %s && break; if [ $i -eq %d ]; then exit 1; else sleep %d; fi; done", bootstrapExtensionRetries, bootstrapSentinelFile, bootstrapExtensionRetries, bootstrapExtensionSleep)
@@ -360,7 +367,7 @@ func UserAgent() string {
360367
}
361368

362369
// ARMClientOptions returns default ARM client options for CAPZ SDK v2 requests.
363-
func ARMClientOptions(azureEnvironment string, extraPolicies ...policy.Policy) (*arm.ClientOptions, error) {
370+
func ARMClientOptions(azureEnvironment, armEndpoint string, extraPolicies ...policy.Policy) (*arm.ClientOptions, error) {
364371
opts := &arm.ClientOptions{}
365372

366373
switch azureEnvironment {
@@ -370,6 +377,21 @@ func ARMClientOptions(azureEnvironment string, extraPolicies ...policy.Policy) (
370377
opts.Cloud = cloud.AzureChina
371378
case USGovernmentCloudName:
372379
opts.Cloud = cloud.AzureGovernment
380+
case StackCloudName:
381+
cloudEnv, err := azure.EnvironmentFromURL(armEndpoint)
382+
if err != nil {
383+
return nil, fmt.Errorf("unable to get Azure Stack cloud environment: %w", err)
384+
}
385+
opts.APIVersion = StackAPIVersionProfile
386+
opts.Cloud = cloud.Configuration{
387+
ActiveDirectoryAuthorityHost: cloudEnv.ActiveDirectoryEndpoint,
388+
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
389+
cloud.ResourceManager: {
390+
Audience: cloudEnv.TokenAudience,
391+
Endpoint: cloudEnv.ResourceManagerEndpoint,
392+
},
393+
},
394+
}
373395
case "":
374396
// No cloud name provided, so leave at defaults.
375397
default:

azure/defaults_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func TestARMClientOptions(t *testing.T) {
3838
tests := []struct {
3939
name string
4040
cloudName string
41+
armEndpoint string
4142
expectedCloud cloud.Configuration
4243
expectError bool
4344
}{
@@ -72,7 +73,7 @@ func TestARMClientOptions(t *testing.T) {
7273
t.Parallel()
7374
g := NewWithT(t)
7475

75-
opts, err := ARMClientOptions(tc.cloudName)
76+
opts, err := ARMClientOptions(tc.cloudName, tc.armEndpoint)
7677
if tc.expectError {
7778
g.Expect(err).To(HaveOccurred())
7879
return
@@ -99,7 +100,7 @@ func TestPerCallPolicies(t *testing.T) {
99100
defer server.Close()
100101

101102
// Call the factory function and ensure it has both PerCallPolicies.
102-
opts, err := ARMClientOptions("")
103+
opts, err := ARMClientOptions("", "")
103104
g.Expect(err).NotTo(HaveOccurred())
104105
g.Expect(opts.PerCallPolicies).To(HaveLen(2))
105106
g.Expect(opts.PerCallPolicies).To(ContainElement(BeAssignableToTypeOf(correlationIDPolicy{})))
@@ -184,7 +185,7 @@ func TestCustomPutPatchHeaderPolicy(t *testing.T) {
184185
// Create options with a custom PUT/PATCH header per-call policy
185186
getterMock := mock_azure.NewMockResourceSpecGetterWithHeaders(mockCtrl)
186187
getterMock.EXPECT().CustomHeaders().Return(tc.headers).AnyTimes()
187-
opts, err := ARMClientOptions("", CustomPutPatchHeaderPolicy{Headers: tc.headers})
188+
opts, err := ARMClientOptions("", "", CustomPutPatchHeaderPolicy{Headers: tc.headers})
188189
g.Expect(err).NotTo(HaveOccurred())
189190

190191
// Create a request

azure/services/availabilitysets/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type AzureClient struct {
3434

3535
// NewClient creates a new availability sets client from an authorizer.
3636
func NewClient(auth azure.Authorizer) (*AzureClient, error) {
37-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
37+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
3838
if err != nil {
3939
return nil, errors.Wrap(err, "failed to create availabilitysets client options")
4040
}

azure/services/disks/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type azureClient struct {
3737

3838
// newClient creates a new disks client from an authorizer.
3939
func newClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) {
40-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
40+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
4141
if err != nil {
4242
return nil, errors.Wrap(err, "failed to create disks client options")
4343
}

azure/services/identities/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type AzureClient struct {
4141

4242
// NewClient creates a new MSI client from an authorizer.
4343
func NewClient(auth azure.Authorizer) (Client, error) {
44-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
44+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
4545
if err != nil {
4646
return nil, errors.Wrap(err, "failed to create identities client options")
4747
}
@@ -54,7 +54,7 @@ func NewClient(auth azure.Authorizer) (Client, error) {
5454

5555
// NewClientBySub creates a new MSI client with a given subscriptionID.
5656
func NewClientBySub(auth azure.Authorizer, subscriptionID string) (Client, error) {
57-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
57+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
5858
if err != nil {
5959
return nil, errors.Wrap(err, "failed to create identities client options")
6060
}

azure/services/inboundnatrules/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ var _ client = (*azureClient)(nil)
4444

4545
// newClient creates a new inbound NAT rules client from an authorizer.
4646
func newClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) {
47-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
47+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
4848
if err != nil {
4949
return nil, errors.Wrap(err, "failed to create inboundnatrules client options")
5050
}

azure/services/loadbalancers/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type azureClient struct {
3939

4040
// newClient creates a new load balancer client from an authorizer.
4141
func newClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) {
42-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
42+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
4343
if err != nil {
4444
return nil, errors.Wrap(err, "failed to get load balancer client options")
4545
}
@@ -86,7 +86,7 @@ func (ac *azureClient) CreateOrUpdateAsync(ctx context.Context, spec azure.Resou
8686
}
8787

8888
// Create a new client that knows how to add etag headers to the request.
89-
clientOpts, err := azure.ARMClientOptions(ac.auth.CloudEnvironment(), extraPolicies...)
89+
clientOpts, err := azure.ARMClientOptions(ac.auth.CloudEnvironment(), ac.auth.BaseURI(), extraPolicies...)
9090
if err != nil {
9191
return nil, nil, errors.Wrap(err, "failed to create loadbalancer client options")
9292
}

azure/services/networkinterfaces/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type azureClient struct {
3737

3838
// NewClient creates a new network interfaces client from an authorizer.
3939
func NewClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureClient, error) { //nolint:revive // leave it as is
40-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
40+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
4141
if err != nil {
4242
return nil, errors.Wrap(err, "failed to create networkinterfaces client options")
4343
}

azure/services/privatedns/link_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type azureVirtualNetworkLinksClient struct {
3737

3838
// newVirtualNetworkLinksClient creates a virtual network links client from an authorizer.
3939
func newVirtualNetworkLinksClient(auth azure.Authorizer, apiCallTimeout time.Duration) (*azureVirtualNetworkLinksClient, error) {
40-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
40+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
4141
if err != nil {
4242
return nil, errors.Wrap(err, "failed to create virtualnetworkslink client options")
4343
}

azure/services/privatedns/record_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type azureRecordsClient struct {
3434

3535
// newRecordSetsClient creates a record sets client from an authorizer.
3636
func newRecordSetsClient(auth azure.Authorizer) (*azureRecordsClient, error) {
37-
opts, err := azure.ARMClientOptions(auth.CloudEnvironment())
37+
opts, err := azure.ARMClientOptions(auth.CloudEnvironment(), auth.BaseURI())
3838
if err != nil {
3939
return nil, errors.Wrap(err, "failed to create recordsets client options")
4040
}

0 commit comments

Comments
 (0)