Skip to content

Commit 3f54f57

Browse files
committed
UPSTREAM: 5532: 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 37a57be commit 3f54f57

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
@@ -27,6 +27,7 @@ import (
2727
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
2828
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
2929
"github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel"
30+
"github.com/Azure/go-autorest/autorest/azure"
3031
"go.opentelemetry.io/otel"
3132

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

115+
const (
116+
// StackAPIVersion is the API version profile to set for ARM clients. See:
117+
// 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
118+
StackAPIVersionProfile = "2020-06-01"
119+
)
120+
114121
var (
115122
// LinuxBootstrapExtensionCommand is the command the VM bootstrap extension will execute to verify Linux nodes bootstrap completes successfully.
116123
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)
@@ -359,7 +366,7 @@ func UserAgent() string {
359366
}
360367

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

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