From dc0e80c7c9c05090172ccf9c10b9c62362904726 Mon Sep 17 00:00:00 2001 From: swetha Date: Wed, 26 Jul 2023 01:53:13 -0700 Subject: [PATCH] Dynamic validation of subscription level registrations at the RP --- go.mod | 1 + go.sum | 4 + pkg/frontend/encryptionathost_test.go | 90 +++ pkg/frontend/encryptionathost_validation.go | 73 +++ pkg/frontend/frontend.go | 14 +- pkg/frontend/generate.go | 2 +- pkg/frontend/openshiftcluster_putorpatch.go | 5 + .../azureclient/mgmt/features/generate.go | 2 +- .../subscriptionfeatureregistrations.go | 15 + .../azureclient/mgmt/features/features.go | 41 +- pkg/util/mocks/frontend/frontend.go | 41 +- pkg/validate/dynamic/encryptionathost_test.go | 75 +-- .../azure-sdk-for-go/sdk/azcore/arm/client.go | 77 +++ .../azure-sdk-for-go/sdk/azcore/arm/doc.go | 9 + .../internal/resource/resource_identifier.go | 224 ++++++++ .../arm/internal/resource/resource_type.go | 114 ++++ .../sdk/azcore/arm/policy/policy.go | 98 ++++ .../sdk/azcore/arm/resource_identifier.go | 23 + .../sdk/azcore/arm/resource_type.go | 40 ++ .../sdk/azcore/arm/runtime/pipeline.go | 64 +++ .../azcore/arm/runtime/policy_bearer_token.go | 99 ++++ .../azcore/arm/runtime/policy_register_rp.go | 331 +++++++++++ .../sdk/azcore/arm/runtime/runtime.go | 24 + .../resources/armfeatures/CHANGELOG.md | 14 + .../resources/armfeatures/LICENSE.txt | 21 + .../resources/armfeatures/README.md | 85 +++ .../resources/armfeatures/assets.json | 6 + .../resources/armfeatures/autorest.md | 13 + .../resources/armfeatures/build.go | 7 + .../resources/armfeatures/ci.yml | 28 + .../resources/armfeatures/client.go | 339 ++++++++++++ .../resources/armfeatures/client_factory.go | 54 ++ .../resources/armfeatures/constants.go | 59 ++ .../resources/armfeatures/feature_client.go | 95 ++++ .../resources/armfeatures/models.go | 249 +++++++++ .../resources/armfeatures/models_serde.go | 520 ++++++++++++++++++ .../resources/armfeatures/response_types.go | 65 +++ ...subscriptionfeatureregistrations_client.go | 338 ++++++++++++ .../resources/armfeatures/time_rfc3339.go | 87 +++ vendor/modules.txt | 7 + 40 files changed, 3393 insertions(+), 60 deletions(-) create mode 100644 pkg/frontend/encryptionathost_test.go create mode 100644 pkg/frontend/encryptionathost_validation.go create mode 100644 pkg/util/azureclient/mgmt/features/subscriptionfeatureregistrations.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/CHANGELOG.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/LICENSE.txt create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/README.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/assets.json create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/autorest.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/build.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/ci.yml create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client_factory.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/constants.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/feature_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models_serde.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/response_types.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/subscriptionfeatureregistrations_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/time_rfc3339.go diff --git a/go.mod b/go.mod index dd0fd687470..c45d1537651 100644 --- a/go.mod +++ b/go.mod @@ -85,6 +85,7 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures v1.1.0 github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect diff --git a/go.sum b/go.sum index 7d6416bf703..08328fb01ee 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,10 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.2 h1:uqM+VoHjVH6zdlkLF2b6O github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.2/go.mod h1:twTKAa1E6hLmSDjLhaCkbTMQKc7p/rNLU40rLxGEOCI= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures v1.1.0 h1:NhvID5juwkPxMUD8hdV3no0nugxk9QM8d5OSLskjOLM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures v1.1.0/go.mod h1:hDdPReNCfyh7kmZm6uKm3uH3OQkGn8gbeb1c/JkmEdE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= diff --git a/pkg/frontend/encryptionathost_test.go b/pkg/frontend/encryptionathost_test.go new file mode 100644 index 00000000000..2556f1116df --- /dev/null +++ b/pkg/frontend/encryptionathost_test.go @@ -0,0 +1,90 @@ +package frontend + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures" + "github.com/golang/mock/gomock" + + "github.com/Azure/ARO-RP/pkg/api" + mock_features "github.com/Azure/ARO-RP/pkg/util/mocks/azureclient/mgmt/features" + utilerror "github.com/Azure/ARO-RP/test/util/error" +) + +func TestValidateEncryptionAtHost(t *testing.T) { + EncryptionAtHostEnabledOrDisabled := func(MasterProfile api.MasterProfile, WorkerProfiles []api.WorkerProfile) *api.OpenShiftCluster { + return &api.OpenShiftCluster{ + Properties: api.OpenShiftClusterProperties{ + MasterProfile: MasterProfile, + WorkerProfiles: WorkerProfiles, + }, + } + } + + EncryptionAtHostFeatureEnabledOrDisabled := func(state armfeatures.SubscriptionFeatureRegistrationState) *armfeatures.SubscriptionFeatureRegistrationsClientGetResponse { + return &armfeatures.SubscriptionFeatureRegistrationsClientGetResponse{ + SubscriptionFeatureRegistration: armfeatures.SubscriptionFeatureRegistration{ + Properties: &armfeatures.SubscriptionFeatureRegistrationProperties{ + State: &state, + }, + }, + } + } + + for _, tt := range []struct { + name string + oc *api.OpenShiftCluster + mockResponse *armfeatures.SubscriptionFeatureRegistrationsClientGetResponse + mockErr error + wantErr string + }{ + { + name: "encryption at host disabled - feature isn't registered", + oc: EncryptionAtHostEnabledOrDisabled(api.MasterProfile{EncryptionAtHost: api.EncryptionAtHostDisabled}, []api.WorkerProfile{{EncryptionAtHost: api.EncryptionAtHostDisabled}}), + mockResponse: EncryptionAtHostFeatureEnabledOrDisabled(armfeatures.SubscriptionFeatureRegistrationStateNotRegistered), + }, + { + name: "encryption at host disabled - feature is registered", + oc: EncryptionAtHostEnabledOrDisabled(api.MasterProfile{EncryptionAtHost: api.EncryptionAtHostDisabled}, []api.WorkerProfile{{EncryptionAtHost: api.EncryptionAtHostDisabled}}), + mockResponse: EncryptionAtHostFeatureEnabledOrDisabled(armfeatures.SubscriptionFeatureRegistrationStateRegistered), + }, + { + name: "encryption at host enabled - feature is registered", + oc: EncryptionAtHostEnabledOrDisabled(api.MasterProfile{EncryptionAtHost: api.EncryptionAtHostEnabled}, []api.WorkerProfile{{EncryptionAtHost: api.EncryptionAtHostEnabled}}), + mockResponse: EncryptionAtHostFeatureEnabledOrDisabled(armfeatures.SubscriptionFeatureRegistrationStateRegistered), + }, + { + name: "encryption at host enabled - feature isn't registered", + oc: EncryptionAtHostEnabledOrDisabled(api.MasterProfile{EncryptionAtHost: api.EncryptionAtHostEnabled}, []api.WorkerProfile{{EncryptionAtHost: api.EncryptionAtHostEnabled}}), + mockResponse: EncryptionAtHostFeatureEnabledOrDisabled(armfeatures.SubscriptionFeatureRegistrationStateNotRegistered), + wantErr: "400: InvalidParameter: armfeatures.SubscriptionFeatureRegistrationProperties: Microsoft.Compute/EncryptionAtHost feature is not enabled for this subscription. Register the feature using 'az feature register --namespace Microsoft.Compute --name EncryptionAtHost'", + }, + { + name: "MasterProfile encryption at host enabled - feature isn't registered", + oc: EncryptionAtHostEnabledOrDisabled(api.MasterProfile{EncryptionAtHost: api.EncryptionAtHostEnabled}, []api.WorkerProfile{{EncryptionAtHost: api.EncryptionAtHostDisabled}}), + mockResponse: EncryptionAtHostFeatureEnabledOrDisabled(armfeatures.SubscriptionFeatureRegistrationStateNotRegistered), + wantErr: "400: InvalidParameter: armfeatures.SubscriptionFeatureRegistrationProperties: Microsoft.Compute/EncryptionAtHost feature is not enabled for this subscription. Register the feature using 'az feature register --namespace Microsoft.Compute --name EncryptionAtHost'", + }, + { + name: "WorkerProfile encryption at host enabled - feature isn't registered", + oc: EncryptionAtHostEnabledOrDisabled(api.MasterProfile{EncryptionAtHost: api.EncryptionAtHostDisabled}, []api.WorkerProfile{{EncryptionAtHost: api.EncryptionAtHostEnabled}}), + mockResponse: EncryptionAtHostFeatureEnabledOrDisabled(armfeatures.SubscriptionFeatureRegistrationStateNotRegistered), + wantErr: "400: InvalidParameter: armfeatures.SubscriptionFeatureRegistrationProperties: Microsoft.Compute/EncryptionAtHost feature is not enabled for this subscription. Register the feature using 'az feature register --namespace Microsoft.Compute --name EncryptionAtHost'", + }, + } { + t.Run(tt.name, func(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + subFeatureRegistrationsClient := mock_features.NewMockSubscriptionFeatureRegistrationsClient(controller) + subFeatureRegistrationsClient.EXPECT().Get(gomock.Any(), "Microsoft.Compute", "EncryptionAtHost", gomock.Any()).Return(*tt.mockResponse, tt.mockErr).AnyTimes() + + err := validateEncryptionAtHost(context.Background(), subFeatureRegistrationsClient, tt.oc) + utilerror.AssertErrorMessage(t, err, tt.wantErr) + }) + } +} diff --git a/pkg/frontend/encryptionathost_validation.go b/pkg/frontend/encryptionathost_validation.go new file mode 100644 index 00000000000..f683b57eb9f --- /dev/null +++ b/pkg/frontend/encryptionathost_validation.go @@ -0,0 +1,73 @@ +package frontend + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures" + + "github.com/Azure/ARO-RP/pkg/api" + "github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/features" +) + +type EncryptionAtHostValidator interface { + ValidateEncryptionAtHost(ctx context.Context, subscriptionID string, oc *api.OpenShiftCluster) error +} + +type encryptionAtHostValidator struct{} + +func (e encryptionAtHostValidator) ValidateEncryptionAtHost(ctx context.Context, subscriptionID string, oc *api.OpenShiftCluster) error { + credential, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return err + } + + subFeatureRegistrationsClient, err := armfeatures.NewSubscriptionFeatureRegistrationsClient(subscriptionID, credential, nil) + if err != nil { + return err + } + return validateEncryptionAtHost(ctx, subFeatureRegistrationsClient, oc) +} + +func validateEncryptionAtHost(ctx context.Context, subFeatureRegistrationsClient features.SubscriptionFeatureRegistrationsClient, oc *api.OpenShiftCluster) error { + encryptionSettings := make(map[api.EncryptionAtHost]bool) + + encryptionSettings[oc.Properties.MasterProfile.EncryptionAtHost] = true + + for _, wp := range oc.Properties.WorkerProfiles { + encryptionSettings[wp.EncryptionAtHost] = true + } + + for setting := range encryptionSettings { + if setting == api.EncryptionAtHostEnabled { + if err := IsRegisteredForEncryptionAtHostFeature(ctx, subFeatureRegistrationsClient); err != nil { + return err + } + + } + } + + return nil +} + +func IsRegisteredForEncryptionAtHostFeature(ctx context.Context, subFeatureRegistrationsClient features.SubscriptionFeatureRegistrationsClient) error { + response, err := subFeatureRegistrationsClient.Get(ctx, "Microsoft.Compute", "EncryptionAtHost", nil) + if err != nil { + return err + } + if *response.Properties.State == armfeatures.SubscriptionFeatureRegistrationStateRegistered { + return nil + } + return &api.CloudError{ + StatusCode: http.StatusBadRequest, + CloudErrorBody: &api.CloudErrorBody{ + Code: api.CloudErrorCodeInvalidParameter, + Message: "Microsoft.Compute/EncryptionAtHost feature is not enabled for this subscription. Register the feature using 'az feature register --namespace Microsoft.Compute --name EncryptionAtHost'", + Target: "armfeatures.SubscriptionFeatureRegistrationProperties", + }, + } +} diff --git a/pkg/frontend/frontend.go b/pkg/frontend/frontend.go index b848780adc1..84477e27fa4 100644 --- a/pkg/frontend/frontend.go +++ b/pkg/frontend/frontend.go @@ -75,9 +75,10 @@ type frontend struct { kubeActionsFactory kubeActionsFactory azureActionsFactory azureActionsFactory - skuValidator SkuValidator - quotaValidator QuotaValidator - providersValidator ProvidersValidator + skuValidator SkuValidator + quotaValidator QuotaValidator + providersValidator ProvidersValidator + encryptionathostValidator EncryptionAtHostValidator clusterEnricher clusterdata.BestEffortEnricher @@ -160,9 +161,10 @@ func NewFrontend(ctx context.Context, kubeActionsFactory: kubeActionsFactory, azureActionsFactory: azureActionsFactory, - quotaValidator: quotaValidator{}, - skuValidator: skuValidator{}, - providersValidator: providersValidator{}, + quotaValidator: quotaValidator{}, + skuValidator: skuValidator{}, + providersValidator: providersValidator{}, + encryptionathostValidator: encryptionAtHostValidator{}, clusterEnricher: enricher, diff --git a/pkg/frontend/generate.go b/pkg/frontend/generate.go index fe017c4bd9f..2fb762f052e 100644 --- a/pkg/frontend/generate.go +++ b/pkg/frontend/generate.go @@ -4,5 +4,5 @@ package frontend // Licensed under the Apache License 2.0. //go:generate rm -rf ../../util/mocks/$GOPACKAGE -//go:generate go run ../../vendor/github.com/golang/mock/mockgen -destination=../util/mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/frontend StreamResponder,QuotaValidator,SkuValidator,ProvidersValidator +//go:generate go run ../../vendor/github.com/golang/mock/mockgen -destination=../util/mocks/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/frontend StreamResponder,QuotaValidator,SkuValidator,ProvidersValidator,EncryptionAtHostValidator //go:generate go run ../../vendor/golang.org/x/tools/cmd/goimports -local=github.com/Azure/ARO-RP -e -w ../util/mocks/$GOPACKAGE/$GOPACKAGE.go diff --git a/pkg/frontend/openshiftcluster_putorpatch.go b/pkg/frontend/openshiftcluster_putorpatch.go index 0ce1146f24e..a0642bcf5eb 100644 --- a/pkg/frontend/openshiftcluster_putorpatch.go +++ b/pkg/frontend/openshiftcluster_putorpatch.go @@ -303,6 +303,11 @@ func (f *frontend) ValidateNewCluster(ctx context.Context, subscription *api.Sub return err } + err = f.encryptionathostValidator.ValidateEncryptionAtHost(ctx, subscription.ID, cluster) + if err != nil { + return err + } + return nil } diff --git a/pkg/util/azureclient/mgmt/features/generate.go b/pkg/util/azureclient/mgmt/features/generate.go index d6270d592a7..3c7ff3e7dbb 100644 --- a/pkg/util/azureclient/mgmt/features/generate.go +++ b/pkg/util/azureclient/mgmt/features/generate.go @@ -4,5 +4,5 @@ package features // Licensed under the Apache License 2.0. //go:generate rm -rf ../../../../util/mocks/$GOPACKAGE -//go:generate go run ../../../../../vendor/github.com/golang/mock/mockgen -destination=../../../../util/mocks/azureclient/mgmt/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/$GOPACKAGE DeploymentsClient,ProvidersClient,ResourceGroupsClient,ResourcesClient +//go:generate go run ../../../../../vendor/github.com/golang/mock/mockgen -destination=../../../../util/mocks/azureclient/mgmt/$GOPACKAGE/$GOPACKAGE.go github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/$GOPACKAGE DeploymentsClient,ProvidersClient,ResourceGroupsClient,ResourcesClient,SubscriptionFeatureRegistrationsClient //go:generate go run ../../../../../vendor/golang.org/x/tools/cmd/goimports -local=github.com/Azure/ARO-RP -e -w ../../../../util/mocks/azureclient/mgmt/$GOPACKAGE/$GOPACKAGE.go diff --git a/pkg/util/azureclient/mgmt/features/subscriptionfeatureregistrations.go b/pkg/util/azureclient/mgmt/features/subscriptionfeatureregistrations.go new file mode 100644 index 00000000000..b55d8a20790 --- /dev/null +++ b/pkg/util/azureclient/mgmt/features/subscriptionfeatureregistrations.go @@ -0,0 +1,15 @@ +package features + +// Copyright (c) Microsoft Corporation. +// Licensed under the Apache License 2.0. + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures" +) + +// SubscriptionFeatureRegistrationsClient is a minimal interface for azure SubscriptionFeatureRegistrationsClient +type SubscriptionFeatureRegistrationsClient interface { + Get(ctx context.Context, providerNamespace string, featureName string, options *armfeatures.SubscriptionFeatureRegistrationsClientGetOptions) (armfeatures.SubscriptionFeatureRegistrationsClientGetResponse, error) +} diff --git a/pkg/util/mocks/azureclient/mgmt/features/features.go b/pkg/util/mocks/azureclient/mgmt/features/features.go index 80e23fac081..d0ff41fdb4a 100644 --- a/pkg/util/mocks/azureclient/mgmt/features/features.go +++ b/pkg/util/mocks/azureclient/mgmt/features/features.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/features (interfaces: DeploymentsClient,ProvidersClient,ResourceGroupsClient,ResourcesClient) +// Source: github.com/Azure/ARO-RP/pkg/util/azureclient/mgmt/features (interfaces: DeploymentsClient,ProvidersClient,ResourceGroupsClient,ResourcesClient,SubscriptionFeatureRegistrationsClient) // Package mock_features is a generated GoMock package. package mock_features @@ -8,6 +8,7 @@ import ( context "context" reflect "reflect" + armfeatures "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures" features "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-07-01/features" autorest "github.com/Azure/go-autorest/autorest" gomock "github.com/golang/mock/gomock" @@ -323,3 +324,41 @@ func (mr *MockResourcesClientMockRecorder) ListByResourceGroup(arg0, arg1, arg2, mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListByResourceGroup", reflect.TypeOf((*MockResourcesClient)(nil).ListByResourceGroup), arg0, arg1, arg2, arg3, arg4) } + +// MockSubscriptionFeatureRegistrationsClient is a mock of SubscriptionFeatureRegistrationsClient interface. +type MockSubscriptionFeatureRegistrationsClient struct { + ctrl *gomock.Controller + recorder *MockSubscriptionFeatureRegistrationsClientMockRecorder +} + +// MockSubscriptionFeatureRegistrationsClientMockRecorder is the mock recorder for MockSubscriptionFeatureRegistrationsClient. +type MockSubscriptionFeatureRegistrationsClientMockRecorder struct { + mock *MockSubscriptionFeatureRegistrationsClient +} + +// NewMockSubscriptionFeatureRegistrationsClient creates a new mock instance. +func NewMockSubscriptionFeatureRegistrationsClient(ctrl *gomock.Controller) *MockSubscriptionFeatureRegistrationsClient { + mock := &MockSubscriptionFeatureRegistrationsClient{ctrl: ctrl} + mock.recorder = &MockSubscriptionFeatureRegistrationsClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSubscriptionFeatureRegistrationsClient) EXPECT() *MockSubscriptionFeatureRegistrationsClientMockRecorder { + return m.recorder +} + +// Get mocks base method. +func (m *MockSubscriptionFeatureRegistrationsClient) Get(arg0 context.Context, arg1, arg2 string, arg3 *armfeatures.SubscriptionFeatureRegistrationsClientGetOptions) (armfeatures.SubscriptionFeatureRegistrationsClientGetResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(armfeatures.SubscriptionFeatureRegistrationsClientGetResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockSubscriptionFeatureRegistrationsClientMockRecorder) Get(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockSubscriptionFeatureRegistrationsClient)(nil).Get), arg0, arg1, arg2, arg3) +} diff --git a/pkg/util/mocks/frontend/frontend.go b/pkg/util/mocks/frontend/frontend.go index 23853a91f2a..60dd3bdb688 100644 --- a/pkg/util/mocks/frontend/frontend.go +++ b/pkg/util/mocks/frontend/frontend.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/Azure/ARO-RP/pkg/frontend (interfaces: StreamResponder,QuotaValidator,SkuValidator,ProvidersValidator) +// Source: github.com/Azure/ARO-RP/pkg/frontend (interfaces: StreamResponder,QuotaValidator,SkuValidator,ProvidersValidator,EncryptionAtHostValidator) // Package mock_frontend is a generated GoMock package. package mock_frontend @@ -10,12 +10,14 @@ import ( http "net/http" reflect "reflect" + policy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" gomock "github.com/golang/mock/gomock" logrus "github.com/sirupsen/logrus" api "github.com/Azure/ARO-RP/pkg/api" env "github.com/Azure/ARO-RP/pkg/env" azureclient "github.com/Azure/ARO-RP/pkg/util/azureclient" + azcore "github.com/Azure/ARO-RP/pkg/util/azureclient/azuresdk/azcore" ) // MockStreamResponder is a mock of StreamResponder interface. @@ -175,3 +177,40 @@ func (mr *MockProvidersValidatorMockRecorder) ValidateProviders(arg0, arg1, arg2 mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateProviders", reflect.TypeOf((*MockProvidersValidator)(nil).ValidateProviders), arg0, arg1, arg2, arg3, arg4) } + +// MockEncryptionAtHostValidator is a mock of EncryptionAtHostValidator interface. +type MockEncryptionAtHostValidator struct { + ctrl *gomock.Controller + recorder *MockEncryptionAtHostValidatorMockRecorder +} + +// MockEncryptionAtHostValidatorMockRecorder is the mock recorder for MockEncryptionAtHostValidator. +type MockEncryptionAtHostValidatorMockRecorder struct { + mock *MockEncryptionAtHostValidator +} + +// NewMockEncryptionAtHostValidator creates a new mock instance. +func NewMockEncryptionAtHostValidator(ctrl *gomock.Controller) *MockEncryptionAtHostValidator { + mock := &MockEncryptionAtHostValidator{ctrl: ctrl} + mock.recorder = &MockEncryptionAtHostValidatorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEncryptionAtHostValidator) EXPECT() *MockEncryptionAtHostValidatorMockRecorder { + return m.recorder +} + +// ValidateEncryptionAtHost mocks base method. +func (m *MockEncryptionAtHostValidator) ValidateEncryptionAtHost(arg0 context.Context, arg1 string, arg2 azcore.TokenCredential, arg3 *policy.ClientOptions, arg4 *api.OpenShiftCluster) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ValidateEncryptionAtHost", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// ValidateEncryptionAtHost indicates an expected call of ValidateEncryptionAtHost. +func (mr *MockEncryptionAtHostValidatorMockRecorder) ValidateEncryptionAtHost(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateEncryptionAtHost", reflect.TypeOf((*MockEncryptionAtHostValidator)(nil).ValidateEncryptionAtHost), arg0, arg1, arg2, arg3, arg4) +} diff --git a/pkg/validate/dynamic/encryptionathost_test.go b/pkg/validate/dynamic/encryptionathost_test.go index 2a5a7e2ee76..4ec8722a408 100644 --- a/pkg/validate/dynamic/encryptionathost_test.go +++ b/pkg/validate/dynamic/encryptionathost_test.go @@ -19,30 +19,38 @@ import ( ) func TestValidateEncryptionAtHost(t *testing.T) { + EncryptionAtHostEnabled := func(MasterVMSize api.VMSize, WorkerVMSize api.VMSize) *api.OpenShiftCluster { + return &api.OpenShiftCluster{ + Properties: api.OpenShiftClusterProperties{ + MasterProfile: api.MasterProfile{ + EncryptionAtHost: api.EncryptionAtHostEnabled, + VMSize: MasterVMSize, + }, + WorkerProfiles: []api.WorkerProfile{{ + EncryptionAtHost: api.EncryptionAtHostEnabled, + VMSize: WorkerVMSize, + }}, + }, + } + } + for _, tt := range []struct { name string oc *api.OpenShiftCluster mocks func(env *mock_env.MockInterface) wantErr string }{ + { + name: "encryption at host disabled", + oc: &api.OpenShiftCluster{}, + }, { name: "encryption at host disabled", oc: &api.OpenShiftCluster{}, }, { name: "encryption at host enabled with valid VM SKU", - oc: &api.OpenShiftCluster{ - Properties: api.OpenShiftClusterProperties{ - MasterProfile: api.MasterProfile{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardD8sV3, - }, - WorkerProfiles: []api.WorkerProfile{{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardD4asV4, - }}, - }, - }, + oc: EncryptionAtHostEnabled(api.VMSizeStandardD8sV3, api.VMSizeStandardD4asV4), mocks: func(env *mock_env.MockInterface) { env.EXPECT().VMSku(string(api.VMSizeStandardD8sV3)). Return(&mgmtcompute.ResourceSku{ @@ -60,18 +68,7 @@ func TestValidateEncryptionAtHost(t *testing.T) { }, { name: "encryption at host enabled with unsupported master VM SKU", - oc: &api.OpenShiftCluster{ - Properties: api.OpenShiftClusterProperties{ - MasterProfile: api.MasterProfile{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardM128ms, - }, - WorkerProfiles: []api.WorkerProfile{{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardD4asV4, - }}, - }, - }, + oc: EncryptionAtHostEnabled(api.VMSizeStandardM128ms, api.VMSizeStandardD4asV4), mocks: func(env *mock_env.MockInterface) { env.EXPECT().VMSku(string(api.VMSizeStandardM128ms)). Return(&mgmtcompute.ResourceSku{ @@ -83,19 +80,8 @@ func TestValidateEncryptionAtHost(t *testing.T) { wantErr: "400: InvalidParameter: properties.masterProfile.encryptionAtHost: VM SKU 'Standard_M128ms' does not support encryption at host.", }, { - name: "encryption at host enabled with unsupported worker VM SKU", - oc: &api.OpenShiftCluster{ - Properties: api.OpenShiftClusterProperties{ - MasterProfile: api.MasterProfile{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardD8sV3, - }, - WorkerProfiles: []api.WorkerProfile{{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardM128ms, - }}, - }, - }, + name: "encryption at host enabled with unsupported worker VM SKU - feature is registered", + oc: EncryptionAtHostEnabled(api.VMSizeStandardD8sV3, api.VMSizeStandardM128ms), mocks: func(env *mock_env.MockInterface) { env.EXPECT().VMSku(string(api.VMSizeStandardD8sV3)). Return(&mgmtcompute.ResourceSku{ @@ -113,19 +99,8 @@ func TestValidateEncryptionAtHost(t *testing.T) { wantErr: "400: InvalidParameter: properties.workerProfiles[0].encryptionAtHost: VM SKU 'Standard_M128ms' does not support encryption at host.", }, { - name: "encryption at host enabled with unknown VM SKU", - oc: &api.OpenShiftCluster{ - Properties: api.OpenShiftClusterProperties{ - MasterProfile: api.MasterProfile{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: "invalid", - }, - WorkerProfiles: []api.WorkerProfile{{ - EncryptionAtHost: api.EncryptionAtHostEnabled, - VMSize: api.VMSizeStandardM128ms, - }}, - }, - }, + name: "encryption at host enabled with unknown VM SKU - feature is registered", + oc: EncryptionAtHostEnabled("invalid", api.VMSizeStandardM128ms), mocks: func(env *mock_env.MockInterface) { env.EXPECT().VMSku("invalid"). Return(nil, errors.New("fake error")) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go new file mode 100644 index 00000000000..94d018d4353 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go @@ -0,0 +1,77 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package arm + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + armruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +// ClientOptions contains configuration settings for a client's pipeline. +type ClientOptions = armpolicy.ClientOptions + +// Client is a HTTP client for use with ARM endpoints. It consists of an endpoint, pipeline, and tracing provider. +type Client struct { + ep string + pl runtime.Pipeline + tr tracing.Tracer +} + +// NewClient creates a new Client instance with the provided values. +// This client is intended to be used with Azure Resource Manager endpoints. +// - clientName - the fully qualified name of the client ("package.Client"); this is used by the tracing provider when creating spans +// - moduleVersion - the version of the containing module; used by the telemetry policy +// - cred - the TokenCredential used to authenticate the request +// - options - optional client configurations; pass nil to accept the default values +func NewClient(clientName, moduleVersion string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) { + pkg, err := shared.ExtractPackageName(clientName) + if err != nil { + return nil, err + } + + if options == nil { + options = &ClientOptions{} + } + + if !options.Telemetry.Disabled { + if err := shared.ValidateModVer(moduleVersion); err != nil { + return nil, err + } + } + + ep := cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint + if c, ok := options.Cloud.Services[cloud.ResourceManager]; ok { + ep = c.Endpoint + } + pl, err := armruntime.NewPipeline(pkg, moduleVersion, cred, runtime.PipelineOptions{}, options) + if err != nil { + return nil, err + } + + tr := options.TracingProvider.NewTracer(clientName, moduleVersion) + return &Client{ep: ep, pl: pl, tr: tr}, nil +} + +// Endpoint returns the service's base URL for this client. +func (c *Client) Endpoint() string { + return c.ep +} + +// Pipeline returns the pipeline for this client. +func (c *Client) Pipeline() runtime.Pipeline { + return c.pl +} + +// Tracer returns the tracer for this client. +func (c *Client) Tracer() tracing.Tracer { + return c.tr +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go new file mode 100644 index 00000000000..1bdd16a3d03 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go @@ -0,0 +1,9 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package arm contains functionality specific to Azure Resource Manager clients. +package arm diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go new file mode 100644 index 00000000000..187fe82b97c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go @@ -0,0 +1,224 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package resource + +import ( + "fmt" + "strings" +) + +const ( + providersKey = "providers" + subscriptionsKey = "subscriptions" + resourceGroupsLowerKey = "resourcegroups" + locationsKey = "locations" + builtInResourceNamespace = "Microsoft.Resources" +) + +// RootResourceID defines the tenant as the root parent of all other ResourceID. +var RootResourceID = &ResourceID{ + Parent: nil, + ResourceType: TenantResourceType, + Name: "", +} + +// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`. +// Don't create this type directly, use ParseResourceID instead. +type ResourceID struct { + // Parent is the parent ResourceID of this instance. + // Can be nil if there is no parent. + Parent *ResourceID + + // SubscriptionID is the subscription ID in this resource ID. + // The value can be empty if the resource ID does not contain a subscription ID. + SubscriptionID string + + // ResourceGroupName is the resource group name in this resource ID. + // The value can be empty if the resource ID does not contain a resource group name. + ResourceGroupName string + + // Provider represents the provider name in this resource ID. + // This is only valid when the resource ID represents a resource provider. + // Example: `/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Insights` + Provider string + + // Location is the location in this resource ID. + // The value can be empty if the resource ID does not contain a location name. + Location string + + // ResourceType represents the type of this resource ID. + ResourceType ResourceType + + // Name is the resource name of this resource ID. + Name string + + isChild bool + stringValue string +} + +// ParseResourceID parses a string to an instance of ResourceID +func ParseResourceID(id string) (*ResourceID, error) { + if len(id) == 0 { + return nil, fmt.Errorf("invalid resource ID: id cannot be empty") + } + + if !strings.HasPrefix(id, "/") { + return nil, fmt.Errorf("invalid resource ID: resource id '%s' must start with '/'", id) + } + + parts := splitStringAndOmitEmpty(id, "/") + + if len(parts) < 2 { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + if !strings.EqualFold(parts[0], subscriptionsKey) && !strings.EqualFold(parts[0], providersKey) { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + return appendNext(RootResourceID, parts, id) +} + +// String returns the string of the ResourceID +func (id *ResourceID) String() string { + if len(id.stringValue) > 0 { + return id.stringValue + } + + if id.Parent == nil { + return "" + } + + builder := strings.Builder{} + builder.WriteString(id.Parent.String()) + + if id.isChild { + builder.WriteString(fmt.Sprintf("/%s", id.ResourceType.lastType())) + if len(id.Name) > 0 { + builder.WriteString(fmt.Sprintf("/%s", id.Name)) + } + } else { + builder.WriteString(fmt.Sprintf("/providers/%s/%s/%s", id.ResourceType.Namespace, id.ResourceType.Type, id.Name)) + } + + id.stringValue = builder.String() + + return id.stringValue +} + +func newResourceID(parent *ResourceID, resourceTypeName string, resourceName string) *ResourceID { + id := &ResourceID{} + id.init(parent, chooseResourceType(resourceTypeName, parent), resourceName, true) + return id +} + +func newResourceIDWithResourceType(parent *ResourceID, resourceType ResourceType, resourceName string) *ResourceID { + id := &ResourceID{} + id.init(parent, resourceType, resourceName, true) + return id +} + +func newResourceIDWithProvider(parent *ResourceID, providerNamespace, resourceTypeName, resourceName string) *ResourceID { + id := &ResourceID{} + id.init(parent, NewResourceType(providerNamespace, resourceTypeName), resourceName, false) + return id +} + +func chooseResourceType(resourceTypeName string, parent *ResourceID) ResourceType { + if strings.EqualFold(resourceTypeName, resourceGroupsLowerKey) { + return ResourceGroupResourceType + } else if strings.EqualFold(resourceTypeName, subscriptionsKey) && parent != nil && parent.ResourceType.String() == TenantResourceType.String() { + return SubscriptionResourceType + } + + return parent.ResourceType.AppendChild(resourceTypeName) +} + +func (id *ResourceID) init(parent *ResourceID, resourceType ResourceType, name string, isChild bool) { + if parent != nil { + id.Provider = parent.Provider + id.SubscriptionID = parent.SubscriptionID + id.ResourceGroupName = parent.ResourceGroupName + id.Location = parent.Location + } + + if resourceType.String() == SubscriptionResourceType.String() { + id.SubscriptionID = name + } + + if resourceType.lastType() == locationsKey { + id.Location = name + } + + if resourceType.String() == ResourceGroupResourceType.String() { + id.ResourceGroupName = name + } + + if resourceType.String() == ProviderResourceType.String() { + id.Provider = name + } + + if parent == nil { + id.Parent = RootResourceID + } else { + id.Parent = parent + } + id.isChild = isChild + id.ResourceType = resourceType + id.Name = name +} + +func appendNext(parent *ResourceID, parts []string, id string) (*ResourceID, error) { + if len(parts) == 0 { + return parent, nil + } + + if len(parts) == 1 { + // subscriptions and resourceGroups are not valid ids without their names + if strings.EqualFold(parts[0], subscriptionsKey) || strings.EqualFold(parts[0], resourceGroupsLowerKey) { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + // resourceGroup must contain either child or provider resource type + if parent.ResourceType.String() == ResourceGroupResourceType.String() { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + return newResourceID(parent, parts[0], ""), nil + } + + if strings.EqualFold(parts[0], providersKey) && (len(parts) == 2 || strings.EqualFold(parts[2], providersKey)) { + //provider resource can only be on a tenant or a subscription parent + if parent.ResourceType.String() != SubscriptionResourceType.String() && parent.ResourceType.String() != TenantResourceType.String() { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + return appendNext(newResourceIDWithResourceType(parent, ProviderResourceType, parts[1]), parts[2:], id) + } + + if len(parts) > 3 && strings.EqualFold(parts[0], providersKey) { + return appendNext(newResourceIDWithProvider(parent, parts[1], parts[2], parts[3]), parts[4:], id) + } + + if len(parts) > 1 && !strings.EqualFold(parts[0], providersKey) { + return appendNext(newResourceID(parent, parts[0], parts[1]), parts[2:], id) + } + + return nil, fmt.Errorf("invalid resource ID: %s", id) +} + +func splitStringAndOmitEmpty(v, sep string) []string { + r := make([]string, 0) + for _, s := range strings.Split(v, sep) { + if len(s) == 0 { + continue + } + r = append(r, s) + } + + return r +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go new file mode 100644 index 00000000000..ca03ac9713d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go @@ -0,0 +1,114 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package resource + +import ( + "fmt" + "strings" +) + +// SubscriptionResourceType is the ResourceType of a subscription +var SubscriptionResourceType = NewResourceType(builtInResourceNamespace, "subscriptions") + +// ResourceGroupResourceType is the ResourceType of a resource group +var ResourceGroupResourceType = NewResourceType(builtInResourceNamespace, "resourceGroups") + +// TenantResourceType is the ResourceType of a tenant +var TenantResourceType = NewResourceType(builtInResourceNamespace, "tenants") + +// ProviderResourceType is the ResourceType of a provider +var ProviderResourceType = NewResourceType(builtInResourceNamespace, "providers") + +// ResourceType represents an Azure resource type, e.g. "Microsoft.Network/virtualNetworks/subnets". +// Don't create this type directly, use ParseResourceType or NewResourceType instead. +type ResourceType struct { + // Namespace is the namespace of the resource type. + // e.g. "Microsoft.Network" in resource type "Microsoft.Network/virtualNetworks/subnets" + Namespace string + + // Type is the full type name of the resource type. + // e.g. "virtualNetworks/subnets" in resource type "Microsoft.Network/virtualNetworks/subnets" + Type string + + // Types is the slice of all the sub-types of this resource type. + // e.g. ["virtualNetworks", "subnets"] in resource type "Microsoft.Network/virtualNetworks/subnets" + Types []string + + stringValue string +} + +// String returns the string of the ResourceType +func (t ResourceType) String() string { + return t.stringValue +} + +// IsParentOf returns true when the receiver is the parent resource type of the child. +func (t ResourceType) IsParentOf(child ResourceType) bool { + if !strings.EqualFold(t.Namespace, child.Namespace) { + return false + } + if len(t.Types) >= len(child.Types) { + return false + } + for i := range t.Types { + if !strings.EqualFold(t.Types[i], child.Types[i]) { + return false + } + } + + return true +} + +// AppendChild creates an instance of ResourceType using the receiver as the parent with childType appended to it. +func (t ResourceType) AppendChild(childType string) ResourceType { + return NewResourceType(t.Namespace, fmt.Sprintf("%s/%s", t.Type, childType)) +} + +// NewResourceType creates an instance of ResourceType using a provider namespace +// such as "Microsoft.Network" and type such as "virtualNetworks/subnets". +func NewResourceType(providerNamespace, typeName string) ResourceType { + return ResourceType{ + Namespace: providerNamespace, + Type: typeName, + Types: splitStringAndOmitEmpty(typeName, "/"), + stringValue: fmt.Sprintf("%s/%s", providerNamespace, typeName), + } +} + +// ParseResourceType parses the ResourceType from a resource type string (e.g. Microsoft.Network/virtualNetworks/subsets) +// or a resource identifier string. +// e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mySubnet) +func ParseResourceType(resourceIDOrType string) (ResourceType, error) { + // split the path into segments + parts := splitStringAndOmitEmpty(resourceIDOrType, "/") + + // There must be at least a namespace and type name + if len(parts) < 1 { + return ResourceType{}, fmt.Errorf("invalid resource ID or type: %s", resourceIDOrType) + } + + // if the type is just subscriptions, it is a built-in type in the Microsoft.Resources namespace + if len(parts) == 1 { + // Simple resource type + return NewResourceType(builtInResourceNamespace, parts[0]), nil + } else if strings.Contains(parts[0], ".") { + // Handle resource types (Microsoft.Compute/virtualMachines, Microsoft.Network/virtualNetworks/subnets) + // it is a full type name + return NewResourceType(parts[0], strings.Join(parts[1:], "/")), nil + } else { + // Check if ResourceID + id, err := ParseResourceID(resourceIDOrType) + if err != nil { + return ResourceType{}, err + } + return NewResourceType(id.ResourceType.Namespace, id.ResourceType.Type), nil + } +} + +func (t ResourceType) lastType() string { + return t.Types[len(t.Types)-1] +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go new file mode 100644 index 00000000000..83cf91e3ecb --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go @@ -0,0 +1,98 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package policy + +import ( + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// BearerTokenOptions configures the bearer token policy's behavior. +type BearerTokenOptions struct { + // AuxiliaryTenants are additional tenant IDs for authenticating cross-tenant requests. + // The policy will add a token from each of these tenants to every request. The + // authenticating user or service principal must be a guest in these tenants, and the + // policy's credential must support multitenant authentication. + AuxiliaryTenants []string + + // Scopes contains the list of permission scopes required for the token. + Scopes []string +} + +// RegistrationOptions configures the registration policy's behavior. +// All zero-value fields will be initialized with their default values. +type RegistrationOptions struct { + policy.ClientOptions + + // MaxAttempts is the total number of times to attempt automatic registration + // in the event that an attempt fails. + // The default value is 3. + // Set to a value less than zero to disable the policy. + MaxAttempts int + + // PollingDelay is the amount of time to sleep between polling intervals. + // The default value is 15 seconds. + // A value less than zero means no delay between polling intervals (not recommended). + PollingDelay time.Duration + + // PollingDuration is the amount of time to wait before abandoning polling. + // The default valule is 5 minutes. + // NOTE: Setting this to a small value might cause the policy to prematurely fail. + PollingDuration time.Duration +} + +// ClientOptions contains configuration settings for a client's pipeline. +type ClientOptions struct { + policy.ClientOptions + + // AuxiliaryTenants are additional tenant IDs for authenticating cross-tenant requests. + // The client will add a token from each of these tenants to every request. The + // authenticating user or service principal must be a guest in these tenants, and the + // client's credential must support multitenant authentication. + AuxiliaryTenants []string + + // DisableRPRegistration disables the auto-RP registration policy. Defaults to false. + DisableRPRegistration bool +} + +// Clone return a deep copy of the current options. +func (o *ClientOptions) Clone() *ClientOptions { + if o == nil { + return nil + } + copiedOptions := *o + copiedOptions.Cloud.Services = copyMap(copiedOptions.Cloud.Services) + copiedOptions.Logging.AllowedHeaders = copyArray(copiedOptions.Logging.AllowedHeaders) + copiedOptions.Logging.AllowedQueryParams = copyArray(copiedOptions.Logging.AllowedQueryParams) + copiedOptions.Retry.StatusCodes = copyArray(copiedOptions.Retry.StatusCodes) + copiedOptions.PerRetryPolicies = copyArray(copiedOptions.PerRetryPolicies) + copiedOptions.PerCallPolicies = copyArray(copiedOptions.PerCallPolicies) + return &copiedOptions +} + +// copyMap return a new map with all the key value pair in the src map +func copyMap[K comparable, V any](src map[K]V) map[K]V { + if src == nil { + return nil + } + copiedMap := make(map[K]V) + for k, v := range src { + copiedMap[k] = v + } + return copiedMap +} + +// copyMap return a new array with all the elements in the src array +func copyArray[T any](src []T) []T { + if src == nil { + return nil + } + copiedArray := make([]T, len(src)) + copy(copiedArray, src) + return copiedArray +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go new file mode 100644 index 00000000000..d35d6374fdc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go @@ -0,0 +1,23 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package arm + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource" +) + +// RootResourceID defines the tenant as the root parent of all other ResourceID. +var RootResourceID = resource.RootResourceID + +// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`. +// Don't create this type directly, use ParseResourceID instead. +type ResourceID = resource.ResourceID + +// ParseResourceID parses a string to an instance of ResourceID +func ParseResourceID(id string) (*ResourceID, error) { + return resource.ParseResourceID(id) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go new file mode 100644 index 00000000000..fc7fbffd260 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go @@ -0,0 +1,40 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package arm + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource" +) + +// SubscriptionResourceType is the ResourceType of a subscription +var SubscriptionResourceType = resource.SubscriptionResourceType + +// ResourceGroupResourceType is the ResourceType of a resource group +var ResourceGroupResourceType = resource.ResourceGroupResourceType + +// TenantResourceType is the ResourceType of a tenant +var TenantResourceType = resource.TenantResourceType + +// ProviderResourceType is the ResourceType of a provider +var ProviderResourceType = resource.ProviderResourceType + +// ResourceType represents an Azure resource type, e.g. "Microsoft.Network/virtualNetworks/subnets". +// Don't create this type directly, use ParseResourceType or NewResourceType instead. +type ResourceType = resource.ResourceType + +// NewResourceType creates an instance of ResourceType using a provider namespace +// such as "Microsoft.Network" and type such as "virtualNetworks/subnets". +func NewResourceType(providerNamespace, typeName string) ResourceType { + return resource.NewResourceType(providerNamespace, typeName) +} + +// ParseResourceType parses the ResourceType from a resource type string (e.g. Microsoft.Network/virtualNetworks/subsets) +// or a resource identifier string. +// e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mySubnet) +func ParseResourceType(resourceIDOrType string) (ResourceType, error) { + return resource.ParseResourceType(resourceIDOrType) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go new file mode 100644 index 00000000000..266c74b17bf --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go @@ -0,0 +1,64 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "errors" + "reflect" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" +) + +// NewPipeline creates a pipeline from connection options. Policies from ClientOptions are +// placed after policies from PipelineOptions. The telemetry policy, when enabled, will +// use the specified module and version info. +func NewPipeline(module, version string, cred azcore.TokenCredential, plOpts azruntime.PipelineOptions, options *armpolicy.ClientOptions) (azruntime.Pipeline, error) { + if options == nil { + options = &armpolicy.ClientOptions{} + } + conf, err := getConfiguration(&options.ClientOptions) + if err != nil { + return azruntime.Pipeline{}, err + } + authPolicy := NewBearerTokenPolicy(cred, &armpolicy.BearerTokenOptions{ + AuxiliaryTenants: options.AuxiliaryTenants, + Scopes: []string{conf.Audience + "/.default"}, + }) + perRetry := make([]azpolicy.Policy, len(plOpts.PerRetry), len(plOpts.PerRetry)+1) + copy(perRetry, plOpts.PerRetry) + plOpts.PerRetry = append(perRetry, authPolicy) + if !options.DisableRPRegistration { + regRPOpts := armpolicy.RegistrationOptions{ClientOptions: options.ClientOptions} + regPolicy, err := NewRPRegistrationPolicy(cred, ®RPOpts) + if err != nil { + return azruntime.Pipeline{}, err + } + perCall := make([]azpolicy.Policy, len(plOpts.PerCall), len(plOpts.PerCall)+1) + copy(perCall, plOpts.PerCall) + plOpts.PerCall = append(perCall, regPolicy) + } + if plOpts.APIVersion.Name == "" { + plOpts.APIVersion.Name = "api-version" + } + return azruntime.NewPipeline(module, version, plOpts, &options.ClientOptions), nil +} + +func getConfiguration(o *azpolicy.ClientOptions) (cloud.ServiceConfiguration, error) { + c := cloud.AzurePublic + if !reflect.ValueOf(o.Cloud).IsZero() { + c = o.Cloud + } + if conf, ok := c.Services[cloud.ResourceManager]; ok && conf.Endpoint != "" && conf.Audience != "" { + return conf, nil + } else { + return conf, errors.New("provided Cloud field is missing Azure Resource Manager configuration") + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go new file mode 100644 index 00000000000..07f15991eb2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/internal/temporal" +) + +const headerAuxiliaryAuthorization = "x-ms-authorization-auxiliary" + +// acquiringResourceState holds data for an auxiliary token request +type acquiringResourceState struct { + ctx context.Context + p *BearerTokenPolicy + tenant string +} + +// acquire acquires or updates the resource; only one +// thread/goroutine at a time ever calls this function +func acquire(state acquiringResourceState) (newResource azcore.AccessToken, newExpiration time.Time, err error) { + tk, err := state.p.cred.GetToken(state.ctx, azpolicy.TokenRequestOptions{ + Scopes: state.p.scopes, + TenantID: state.tenant, + }) + if err != nil { + return azcore.AccessToken{}, time.Time{}, err + } + return tk, tk.ExpiresOn, nil +} + +// BearerTokenPolicy authorizes requests with bearer tokens acquired from a TokenCredential. +type BearerTokenPolicy struct { + auxResources map[string]*temporal.Resource[azcore.AccessToken, acquiringResourceState] + btp *azruntime.BearerTokenPolicy + cred azcore.TokenCredential + scopes []string +} + +// NewBearerTokenPolicy creates a policy object that authorizes requests with bearer tokens. +// cred: an azcore.TokenCredential implementation such as a credential object from azidentity +// opts: optional settings. Pass nil to accept default values; this is the same as passing a zero-value options. +func NewBearerTokenPolicy(cred azcore.TokenCredential, opts *armpolicy.BearerTokenOptions) *BearerTokenPolicy { + if opts == nil { + opts = &armpolicy.BearerTokenOptions{} + } + p := &BearerTokenPolicy{cred: cred} + p.auxResources = make(map[string]*temporal.Resource[azcore.AccessToken, acquiringResourceState], len(opts.AuxiliaryTenants)) + for _, t := range opts.AuxiliaryTenants { + p.auxResources[t] = temporal.NewResource(acquire) + } + p.scopes = make([]string, len(opts.Scopes)) + copy(p.scopes, opts.Scopes) + p.btp = azruntime.NewBearerTokenPolicy(cred, opts.Scopes, &azpolicy.BearerTokenOptions{ + AuthorizationHandler: azpolicy.AuthorizationHandler{OnRequest: p.onRequest}, + }) + return p +} + +// onRequest authorizes requests with one or more bearer tokens +func (b *BearerTokenPolicy) onRequest(req *azpolicy.Request, authNZ func(azpolicy.TokenRequestOptions) error) error { + // authorize the request with a token for the primary tenant + err := authNZ(azpolicy.TokenRequestOptions{Scopes: b.scopes}) + if err != nil || len(b.auxResources) == 0 { + return err + } + // add tokens for auxiliary tenants + as := acquiringResourceState{ + ctx: req.Raw().Context(), + p: b, + } + auxTokens := make([]string, 0, len(b.auxResources)) + for tenant, er := range b.auxResources { + as.tenant = tenant + auxTk, err := er.Get(as) + if err != nil { + return err + } + auxTokens = append(auxTokens, fmt.Sprintf("%s%s", shared.BearerTokenPrefix, auxTk.Token)) + } + req.Raw().Header.Set(headerAuxiliaryAuthorization, strings.Join(auxTokens, ", ")) + return nil +} + +// Do authorizes a request with a bearer token +func (b *BearerTokenPolicy) Do(req *azpolicy.Request) (*http.Response, error) { + return b.btp.Do(req) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go new file mode 100644 index 00000000000..49e6608070f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go @@ -0,0 +1,331 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/internal/log" +) + +const ( + // LogRPRegistration entries contain information specific to the automatic registration of an RP. + // Entries of this classification are written IFF the policy needs to take any action. + LogRPRegistration log.Event = "RPRegistration" +) + +// init sets any default values +func setDefaults(r *armpolicy.RegistrationOptions) { + if r.MaxAttempts == 0 { + r.MaxAttempts = 3 + } else if r.MaxAttempts < 0 { + r.MaxAttempts = 0 + } + if r.PollingDelay == 0 { + r.PollingDelay = 15 * time.Second + } else if r.PollingDelay < 0 { + r.PollingDelay = 0 + } + if r.PollingDuration == 0 { + r.PollingDuration = 5 * time.Minute + } +} + +// NewRPRegistrationPolicy creates a policy object configured using the specified options. +// The policy controls whether an unregistered resource provider should automatically be +// registered. See https://aka.ms/rps-not-found for more information. +func NewRPRegistrationPolicy(cred azcore.TokenCredential, o *armpolicy.RegistrationOptions) (azpolicy.Policy, error) { + if o == nil { + o = &armpolicy.RegistrationOptions{} + } + conf, err := getConfiguration(&o.ClientOptions) + if err != nil { + return nil, err + } + authPolicy := NewBearerTokenPolicy(cred, &armpolicy.BearerTokenOptions{Scopes: []string{conf.Audience + "/.default"}}) + p := &rpRegistrationPolicy{ + endpoint: conf.Endpoint, + pipeline: runtime.NewPipeline(shared.Module, shared.Version, runtime.PipelineOptions{PerRetry: []azpolicy.Policy{authPolicy}}, &o.ClientOptions), + options: *o, + } + // init the copy + setDefaults(&p.options) + return p, nil +} + +type rpRegistrationPolicy struct { + endpoint string + pipeline runtime.Pipeline + options armpolicy.RegistrationOptions +} + +func (r *rpRegistrationPolicy) Do(req *azpolicy.Request) (*http.Response, error) { + if r.options.MaxAttempts == 0 { + // policy is disabled + return req.Next() + } + const unregisteredRPCode = "MissingSubscriptionRegistration" + const registeredState = "Registered" + var rp string + var resp *http.Response + for attempts := 0; attempts < r.options.MaxAttempts; attempts++ { + var err error + // make the original request + resp, err = req.Next() + // getting a 409 is the first indication that the RP might need to be registered, check error response + if err != nil || resp.StatusCode != http.StatusConflict { + return resp, err + } + var reqErr requestError + if err = runtime.UnmarshalAsJSON(resp, &reqErr); err != nil { + return resp, err + } + if reqErr.ServiceError == nil { + // missing service error info. just return the response + // to the caller so its error unmarshalling will kick in + return resp, err + } + if !strings.EqualFold(reqErr.ServiceError.Code, unregisteredRPCode) { + // not a 409 due to unregistered RP. just return the response + // to the caller so its error unmarshalling will kick in + return resp, err + } + // RP needs to be registered. start by getting the subscription ID from the original request + subID, err := getSubscription(req.Raw().URL.Path) + if err != nil { + return resp, err + } + // now get the RP from the error + rp, err = getProvider(reqErr) + if err != nil { + return resp, err + } + logRegistrationExit := func(v interface{}) { + log.Writef(LogRPRegistration, "END registration for %s: %v", rp, v) + } + log.Writef(LogRPRegistration, "BEGIN registration for %s", rp) + // create client and make the registration request + // we use the scheme and host from the original request + rpOps := &providersOperations{ + p: r.pipeline, + u: r.endpoint, + subID: subID, + } + if _, err = rpOps.Register(req.Raw().Context(), rp); err != nil { + logRegistrationExit(err) + return resp, err + } + // RP was registered, however we need to wait for the registration to complete + pollCtx, pollCancel := context.WithTimeout(req.Raw().Context(), r.options.PollingDuration) + var lastRegState string + for { + // get the current registration state + getResp, err := rpOps.Get(pollCtx, rp) + if err != nil { + pollCancel() + logRegistrationExit(err) + return resp, err + } + if getResp.Provider.RegistrationState != nil && !strings.EqualFold(*getResp.Provider.RegistrationState, lastRegState) { + // registration state has changed, or was updated for the first time + lastRegState = *getResp.Provider.RegistrationState + log.Writef(LogRPRegistration, "registration state is %s", lastRegState) + } + if strings.EqualFold(lastRegState, registeredState) { + // registration complete + pollCancel() + logRegistrationExit(lastRegState) + break + } + // wait before trying again + select { + case <-time.After(r.options.PollingDelay): + // continue polling + case <-pollCtx.Done(): + pollCancel() + logRegistrationExit(pollCtx.Err()) + return resp, pollCtx.Err() + } + } + // RP was successfully registered, retry the original request + err = req.RewindBody() + if err != nil { + return resp, err + } + } + // if we get here it means we exceeded the number of attempts + return resp, fmt.Errorf("exceeded attempts to register %s", rp) +} + +func getSubscription(path string) (string, error) { + parts := strings.Split(path, "/") + for i, v := range parts { + if v == "subscriptions" && (i+1) < len(parts) { + return parts[i+1], nil + } + } + return "", fmt.Errorf("failed to obtain subscription ID from %s", path) +} + +func getProvider(re requestError) (string, error) { + if len(re.ServiceError.Details) > 0 { + return re.ServiceError.Details[0].Target, nil + } + return "", errors.New("unexpected empty Details") +} + +// minimal error definitions to simplify detection +type requestError struct { + ServiceError *serviceError `json:"error"` +} + +type serviceError struct { + Code string `json:"code"` + Details []serviceErrorDetails `json:"details"` +} + +type serviceErrorDetails struct { + Code string `json:"code"` + Target string `json:"target"` +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +// the following code was copied from module armresources, providers.go and models.go +// only the minimum amount of code was copied to get this working and some edits were made. +/////////////////////////////////////////////////////////////////////////////////////////////// + +type providersOperations struct { + p runtime.Pipeline + u string + subID string +} + +// Get - Gets the specified resource provider. +func (client *providersOperations) Get(ctx context.Context, resourceProviderNamespace string) (providerResponse, error) { + req, err := client.getCreateRequest(ctx, resourceProviderNamespace) + if err != nil { + return providerResponse{}, err + } + resp, err := client.p.Do(req) + if err != nil { + return providerResponse{}, err + } + result, err := client.getHandleResponse(resp) + if err != nil { + return providerResponse{}, err + } + return result, nil +} + +// getCreateRequest creates the Get request. +func (client *providersOperations) getCreateRequest(ctx context.Context, resourceProviderNamespace string) (*azpolicy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}" + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.u, urlPath)) + if err != nil { + return nil, err + } + query := req.Raw().URL.Query() + query.Set("api-version", "2019-05-01") + req.Raw().URL.RawQuery = query.Encode() + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *providersOperations) getHandleResponse(resp *http.Response) (providerResponse, error) { + if !runtime.HasStatusCode(resp, http.StatusOK) { + return providerResponse{}, exported.NewResponseError(resp) + } + result := providerResponse{RawResponse: resp} + err := runtime.UnmarshalAsJSON(resp, &result.Provider) + if err != nil { + return providerResponse{}, err + } + return result, err +} + +// Register - Registers a subscription with a resource provider. +func (client *providersOperations) Register(ctx context.Context, resourceProviderNamespace string) (providerResponse, error) { + req, err := client.registerCreateRequest(ctx, resourceProviderNamespace) + if err != nil { + return providerResponse{}, err + } + resp, err := client.p.Do(req) + if err != nil { + return providerResponse{}, err + } + result, err := client.registerHandleResponse(resp) + if err != nil { + return providerResponse{}, err + } + return result, nil +} + +// registerCreateRequest creates the Register request. +func (client *providersOperations) registerCreateRequest(ctx context.Context, resourceProviderNamespace string) (*azpolicy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register" + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.u, urlPath)) + if err != nil { + return nil, err + } + query := req.Raw().URL.Query() + query.Set("api-version", "2019-05-01") + req.Raw().URL.RawQuery = query.Encode() + return req, nil +} + +// registerHandleResponse handles the Register response. +func (client *providersOperations) registerHandleResponse(resp *http.Response) (providerResponse, error) { + if !runtime.HasStatusCode(resp, http.StatusOK) { + return providerResponse{}, exported.NewResponseError(resp) + } + result := providerResponse{RawResponse: resp} + err := runtime.UnmarshalAsJSON(resp, &result.Provider) + if err != nil { + return providerResponse{}, err + } + return result, err +} + +// ProviderResponse is the response envelope for operations that return a Provider type. +type providerResponse struct { + // Resource provider information. + Provider *provider + + // RawResponse contains the underlying HTTP response. + RawResponse *http.Response +} + +// Provider - Resource provider information. +type provider struct { + // The provider ID. + ID *string `json:"id,omitempty"` + + // The namespace of the resource provider. + Namespace *string `json:"namespace,omitempty"` + + // The registration policy of the resource provider. + RegistrationPolicy *string `json:"registrationPolicy,omitempty"` + + // The registration state of the resource provider. + RegistrationState *string `json:"registrationState,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go new file mode 100644 index 00000000000..1400d43799f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go @@ -0,0 +1,24 @@ +//go:build go1.16 +// +build go1.16 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + +func init() { + cloud.AzureChina.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{ + Audience: "https://management.core.chinacloudapi.cn", + Endpoint: "https://management.chinacloudapi.cn", + } + cloud.AzureGovernment.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{ + Audience: "https://management.core.usgovcloudapi.net", + Endpoint: "https://management.usgovcloudapi.net", + } + cloud.AzurePublic.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{ + Audience: "https://management.core.windows.net/", + Endpoint: "https://management.azure.com", + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/CHANGELOG.md new file mode 100644 index 00000000000..3beb23d2c9a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/CHANGELOG.md @@ -0,0 +1,14 @@ +# Release History + +## 1.1.0 (2023-03-27) +### Features Added + +- New struct `ClientFactory` which is a client factory used to create any client in this module + +## 1.0.0 (2022-05-16) + +The package of `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures` is using our [next generation design principles](https://azure.github.io/azure-sdk/general_introduction.html) since version 1.0.0, which contains breaking changes. + +To migrate the existing applications to the latest version, please refer to [Migration Guide](https://aka.ms/azsdk/go/mgmt/migration). + +To learn more, please refer to our documentation [Quick Start](https://aka.ms/azsdk/go/mgmt). \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/LICENSE.txt new file mode 100644 index 00000000000..dc0c2ffb3dc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/README.md new file mode 100644 index 00000000000..92507eda630 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/README.md @@ -0,0 +1,85 @@ +# Azure Features Module for Go + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures) + +The `armfeatures` module provides operations for working with Azure Features. + +[Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/resourcemanager/resources/armfeatures) + +# Getting started + +## Prerequisites + +- an [Azure subscription](https://azure.microsoft.com/free/) +- Go 1.18 or above (You could download and install the latest version of Go from [here](https://go.dev/doc/install). It will replace the existing Go on your machine. If you want to install multiple Go versions on the same machine, you could refer this [doc](https://go.dev/doc/manage-install).) + +## Install the package + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Install the Azure Features module: + +```sh +go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures +``` + +## Authorization + +When creating a client, you will need to provide a credential for authenticating with Azure Features. The `azidentity` module provides facilities for various ways of authenticating with Azure including client/secret, certificate, managed identity, and more. + +```go +cred, err := azidentity.NewDefaultAzureCredential(nil) +``` + +For more information on authentication, please see the documentation for `azidentity` at [pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity). + +## Client Factory + +Azure Features module consists of one or more clients. We provide a client factory which could be used to create any client in this module. + +```go +clientFactory, err := armfeatures.NewClientFactory(, cred, nil) +``` + +You can use `ClientOptions` in package `github.com/Azure/azure-sdk-for-go/sdk/azcore/arm` to set endpoint to connect with public and sovereign clouds as well as Azure Stack. For more information, please see the documentation for `azcore` at [pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore). + +```go +options := arm.ClientOptions { + ClientOptions: azcore.ClientOptions { + Cloud: cloud.AzureChina, + }, +} +clientFactory, err := armfeatures.NewClientFactory(, cred, &options) +``` + +## Clients + +A client groups a set of related APIs, providing access to its functionality. Create one or more clients to access the APIs you require using client factory. + +```go +client := clientFactory.NewClient() +``` + +## Provide Feedback + +If you encounter bugs or have suggestions, please +[open an issue](https://github.com/Azure/azure-sdk-for-go/issues) and assign the `Features` label. + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. +For details, visit [https://cla.microsoft.com](https://cla.microsoft.com). + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only +need to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information, see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/assets.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/assets.json new file mode 100644 index 00000000000..0c8400cedf3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/assets.json @@ -0,0 +1,6 @@ +{ + "AssetsRepo": "Azure/azure-sdk-assets", + "AssetsRepoPrefixPath": "go", + "TagPrefix": "go/resourcemanager/resources/armfeatures", + "Tag": "go/resourcemanager/resources/armfeatures_314d60e072" +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/autorest.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/autorest.md new file mode 100644 index 00000000000..e5ed13cb7e7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/autorest.md @@ -0,0 +1,13 @@ +### AutoRest Configuration + +> see https://aka.ms/autorest + +``` yaml +azure-arm: true +require: +- https://github.com/Azure/azure-rest-api-specs/blob/0cc5e2efd6ffccf30e80d1e150b488dd87198b94/specification/resources/resource-manager/readme.md +- https://github.com/Azure/azure-rest-api-specs/blob/0cc5e2efd6ffccf30e80d1e150b488dd87198b94/specification/resources/resource-manager/readme.go.md +license-header: MICROSOFT_MIT_NO_VERSION +module-version: 1.1.0 +package-features: true +``` \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/build.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/build.go new file mode 100644 index 00000000000..0fee408476a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/build.go @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +// This file enables 'go generate' to regenerate this specific SDK +//go:generate pwsh ../../../../eng/scripts/build.ps1 -skipBuild -cleanGenerated -format -tidy -generate resourcemanager/resources/armfeatures + +package armfeatures diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/ci.yml new file mode 100644 index 00000000000..cc73e50395b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/ci.yml @@ -0,0 +1,28 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/resources/armfeatures/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/resources/armfeatures/ + +stages: +- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + IncludeRelease: true + ServiceDirectory: 'resourcemanager/resources/armfeatures' diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client.go new file mode 100644 index 00000000000..4d8ac38fe16 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client.go @@ -0,0 +1,339 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import ( + "context" + "errors" + "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/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// Client contains the methods for the Features group. +// Don't use this type directly, use NewClient() instead. +type Client struct { + internal *arm.Client + subscriptionID string +} + +// NewClient creates a new instance of Client with the specified values. +// - subscriptionID - The Azure subscription ID. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*Client, error) { + cl, err := arm.NewClient(moduleName+".Client", moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &Client{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// Get - Gets the preview feature with the specified name. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - resourceProviderNamespace - The resource provider namespace for the feature. +// - featureName - The name of the feature to get. +// - options - ClientGetOptions contains the optional parameters for the Client.Get method. +func (client *Client) Get(ctx context.Context, resourceProviderNamespace string, featureName string, options *ClientGetOptions) (ClientGetResponse, error) { + req, err := client.getCreateRequest(ctx, resourceProviderNamespace, featureName, options) + if err != nil { + return ClientGetResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientGetResponse{}, runtime.NewResponseError(resp) + } + return client.getHandleResponse(resp) +} + +// getCreateRequest creates the Get request. +func (client *Client) getCreateRequest(ctx context.Context, resourceProviderNamespace string, featureName string, options *ClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features/{featureName}" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if featureName == "" { + return nil, errors.New("parameter featureName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{featureName}", url.PathEscape(featureName)) + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json, text/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *Client) getHandleResponse(resp *http.Response) (ClientGetResponse, error) { + result := ClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FeatureResult); err != nil { + return ClientGetResponse{}, err + } + return result, nil +} + +// NewListPager - Gets all the preview features in a provider namespace that are available through AFEC for the subscription. +// +// Generated from API version 2021-07-01 +// - resourceProviderNamespace - The namespace of the resource provider for getting features. +// - options - ClientListOptions contains the optional parameters for the Client.NewListPager method. +func (client *Client) NewListPager(resourceProviderNamespace string, options *ClientListOptions) *runtime.Pager[ClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListResponse]{ + More: func(page ClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListResponse) (ClientListResponse, error) { + var req *policy.Request + var err error + if page == nil { + req, err = client.listCreateRequest(ctx, resourceProviderNamespace, options) + } else { + req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink) + } + if err != nil { + return ClientListResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientListResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientListResponse{}, runtime.NewResponseError(resp) + } + return client.listHandleResponse(resp) + }, + }) +} + +// listCreateRequest creates the List request. +func (client *Client) listCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json, text/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *Client) listHandleResponse(resp *http.Response) (ClientListResponse, error) { + result := ClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FeatureOperationsListResult); err != nil { + return ClientListResponse{}, err + } + return result, nil +} + +// NewListAllPager - Gets all the preview features that are available through AFEC for the subscription. +// +// Generated from API version 2021-07-01 +// - options - ClientListAllOptions contains the optional parameters for the Client.NewListAllPager method. +func (client *Client) NewListAllPager(options *ClientListAllOptions) *runtime.Pager[ClientListAllResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListAllResponse]{ + More: func(page ClientListAllResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListAllResponse) (ClientListAllResponse, error) { + var req *policy.Request + var err error + if page == nil { + req, err = client.listAllCreateRequest(ctx, options) + } else { + req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink) + } + if err != nil { + return ClientListAllResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientListAllResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientListAllResponse{}, runtime.NewResponseError(resp) + } + return client.listAllHandleResponse(resp) + }, + }) +} + +// listAllCreateRequest creates the ListAll request. +func (client *Client) listAllCreateRequest(ctx context.Context, options *ClientListAllOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/features" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json, text/json"} + return req, nil +} + +// listAllHandleResponse handles the ListAll response. +func (client *Client) listAllHandleResponse(resp *http.Response) (ClientListAllResponse, error) { + result := ClientListAllResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FeatureOperationsListResult); err != nil { + return ClientListAllResponse{}, err + } + return result, nil +} + +// Register - Registers the preview feature for the subscription. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - resourceProviderNamespace - The namespace of the resource provider. +// - featureName - The name of the feature to register. +// - options - ClientRegisterOptions contains the optional parameters for the Client.Register method. +func (client *Client) Register(ctx context.Context, resourceProviderNamespace string, featureName string, options *ClientRegisterOptions) (ClientRegisterResponse, error) { + req, err := client.registerCreateRequest(ctx, resourceProviderNamespace, featureName, options) + if err != nil { + return ClientRegisterResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientRegisterResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientRegisterResponse{}, runtime.NewResponseError(resp) + } + return client.registerHandleResponse(resp) +} + +// registerCreateRequest creates the Register request. +func (client *Client) registerCreateRequest(ctx context.Context, resourceProviderNamespace string, featureName string, options *ClientRegisterOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features/{featureName}/register" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if featureName == "" { + return nil, errors.New("parameter featureName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{featureName}", url.PathEscape(featureName)) + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json, text/json"} + return req, nil +} + +// registerHandleResponse handles the Register response. +func (client *Client) registerHandleResponse(resp *http.Response) (ClientRegisterResponse, error) { + result := ClientRegisterResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FeatureResult); err != nil { + return ClientRegisterResponse{}, err + } + return result, nil +} + +// Unregister - Unregisters the preview feature for the subscription. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - resourceProviderNamespace - The namespace of the resource provider. +// - featureName - The name of the feature to unregister. +// - options - ClientUnregisterOptions contains the optional parameters for the Client.Unregister method. +func (client *Client) Unregister(ctx context.Context, resourceProviderNamespace string, featureName string, options *ClientUnregisterOptions) (ClientUnregisterResponse, error) { + req, err := client.unregisterCreateRequest(ctx, resourceProviderNamespace, featureName, options) + if err != nil { + return ClientUnregisterResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientUnregisterResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientUnregisterResponse{}, runtime.NewResponseError(resp) + } + return client.unregisterHandleResponse(resp) +} + +// unregisterCreateRequest creates the Unregister request. +func (client *Client) unregisterCreateRequest(ctx context.Context, resourceProviderNamespace string, featureName string, options *ClientUnregisterOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features/{featureName}/unregister" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if featureName == "" { + return nil, errors.New("parameter featureName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{featureName}", url.PathEscape(featureName)) + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json, text/json"} + return req, nil +} + +// unregisterHandleResponse handles the Unregister response. +func (client *Client) unregisterHandleResponse(resp *http.Response) (ClientUnregisterResponse, error) { + result := ClientUnregisterResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FeatureResult); err != nil { + return ClientUnregisterResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client_factory.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client_factory.go new file mode 100644 index 00000000000..cd7593eced4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/client_factory.go @@ -0,0 +1,54 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" +) + +// ClientFactory is a client factory used to create any client in this module. +// Don't use this type directly, use NewClientFactory instead. +type ClientFactory struct { + subscriptionID string + credential azcore.TokenCredential + options *arm.ClientOptions +} + +// NewClientFactory creates a new instance of ClientFactory with the specified values. +// The parameter values will be propagated to any client created from this factory. +// - subscriptionID - The Azure subscription ID. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewClientFactory(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ClientFactory, error) { + _, err := arm.NewClient(moduleName+".ClientFactory", moduleVersion, credential, options) + if err != nil { + return nil, err + } + return &ClientFactory{ + subscriptionID: subscriptionID, credential: credential, + options: options.Clone(), + }, nil +} + +func (c *ClientFactory) NewFeatureClient() *FeatureClient { + subClient, _ := NewFeatureClient(c.credential, c.options) + return subClient +} + +func (c *ClientFactory) NewClient() *Client { + subClient, _ := NewClient(c.subscriptionID, c.credential, c.options) + return subClient +} + +func (c *ClientFactory) NewSubscriptionFeatureRegistrationsClient() *SubscriptionFeatureRegistrationsClient { + subClient, _ := NewSubscriptionFeatureRegistrationsClient(c.subscriptionID, c.credential, c.options) + return subClient +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/constants.go new file mode 100644 index 00000000000..30bb2b1692d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/constants.go @@ -0,0 +1,59 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +const ( + moduleName = "armfeatures" + moduleVersion = "v1.1.0" +) + +// SubscriptionFeatureRegistrationApprovalType - The feature approval type. +type SubscriptionFeatureRegistrationApprovalType string + +const ( + SubscriptionFeatureRegistrationApprovalTypeApprovalRequired SubscriptionFeatureRegistrationApprovalType = "ApprovalRequired" + SubscriptionFeatureRegistrationApprovalTypeAutoApproval SubscriptionFeatureRegistrationApprovalType = "AutoApproval" + SubscriptionFeatureRegistrationApprovalTypeNotSpecified SubscriptionFeatureRegistrationApprovalType = "NotSpecified" +) + +// PossibleSubscriptionFeatureRegistrationApprovalTypeValues returns the possible values for the SubscriptionFeatureRegistrationApprovalType const type. +func PossibleSubscriptionFeatureRegistrationApprovalTypeValues() []SubscriptionFeatureRegistrationApprovalType { + return []SubscriptionFeatureRegistrationApprovalType{ + SubscriptionFeatureRegistrationApprovalTypeApprovalRequired, + SubscriptionFeatureRegistrationApprovalTypeAutoApproval, + SubscriptionFeatureRegistrationApprovalTypeNotSpecified, + } +} + +// SubscriptionFeatureRegistrationState - The state. +type SubscriptionFeatureRegistrationState string + +const ( + SubscriptionFeatureRegistrationStateNotRegistered SubscriptionFeatureRegistrationState = "NotRegistered" + SubscriptionFeatureRegistrationStateNotSpecified SubscriptionFeatureRegistrationState = "NotSpecified" + SubscriptionFeatureRegistrationStatePending SubscriptionFeatureRegistrationState = "Pending" + SubscriptionFeatureRegistrationStateRegistered SubscriptionFeatureRegistrationState = "Registered" + SubscriptionFeatureRegistrationStateRegistering SubscriptionFeatureRegistrationState = "Registering" + SubscriptionFeatureRegistrationStateUnregistered SubscriptionFeatureRegistrationState = "Unregistered" + SubscriptionFeatureRegistrationStateUnregistering SubscriptionFeatureRegistrationState = "Unregistering" +) + +// PossibleSubscriptionFeatureRegistrationStateValues returns the possible values for the SubscriptionFeatureRegistrationState const type. +func PossibleSubscriptionFeatureRegistrationStateValues() []SubscriptionFeatureRegistrationState { + return []SubscriptionFeatureRegistrationState{ + SubscriptionFeatureRegistrationStateNotRegistered, + SubscriptionFeatureRegistrationStateNotSpecified, + SubscriptionFeatureRegistrationStatePending, + SubscriptionFeatureRegistrationStateRegistered, + SubscriptionFeatureRegistrationStateRegistering, + SubscriptionFeatureRegistrationStateUnregistered, + SubscriptionFeatureRegistrationStateUnregistering, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/feature_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/feature_client.go new file mode 100644 index 00000000000..55795aedf0e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/feature_client.go @@ -0,0 +1,95 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import ( + "context" + "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/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" +) + +// FeatureClient contains the methods for the FeatureClient group. +// Don't use this type directly, use NewFeatureClient() instead. +type FeatureClient struct { + internal *arm.Client +} + +// NewFeatureClient creates a new instance of FeatureClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewFeatureClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*FeatureClient, error) { + cl, err := arm.NewClient(moduleName+".FeatureClient", moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &FeatureClient{ + internal: cl, + } + return client, nil +} + +// NewListOperationsPager - Lists all of the available Microsoft.Features REST API operations. +// +// Generated from API version 2021-07-01 +// - options - FeatureClientListOperationsOptions contains the optional parameters for the FeatureClient.NewListOperationsPager +// method. +func (client *FeatureClient) NewListOperationsPager(options *FeatureClientListOperationsOptions) *runtime.Pager[FeatureClientListOperationsResponse] { + return runtime.NewPager(runtime.PagingHandler[FeatureClientListOperationsResponse]{ + More: func(page FeatureClientListOperationsResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *FeatureClientListOperationsResponse) (FeatureClientListOperationsResponse, error) { + var req *policy.Request + var err error + if page == nil { + req, err = client.listOperationsCreateRequest(ctx, options) + } else { + req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink) + } + if err != nil { + return FeatureClientListOperationsResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return FeatureClientListOperationsResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return FeatureClientListOperationsResponse{}, runtime.NewResponseError(resp) + } + return client.listOperationsHandleResponse(resp) + }, + }) +} + +// listOperationsCreateRequest creates the ListOperations request. +func (client *FeatureClient) listOperationsCreateRequest(ctx context.Context, options *FeatureClientListOperationsOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Features/operations" + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json, text/json"} + return req, nil +} + +// listOperationsHandleResponse handles the ListOperations response. +func (client *FeatureClient) listOperationsHandleResponse(resp *http.Response) (FeatureClientListOperationsResponse, error) { + result := FeatureClientListOperationsResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.OperationListResult); err != nil { + return FeatureClientListOperationsResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models.go new file mode 100644 index 00000000000..09eab296c3c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models.go @@ -0,0 +1,249 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import "time" + +// AuthorizationProfile - Authorization Profile +type AuthorizationProfile struct { + // READ-ONLY; The approved time + ApprovedTime *time.Time `json:"approvedTime,omitempty" azure:"ro"` + + // READ-ONLY; The approver + Approver *string `json:"approver,omitempty" azure:"ro"` + + // READ-ONLY; The requested time + RequestedTime *time.Time `json:"requestedTime,omitempty" azure:"ro"` + + // READ-ONLY; The requester + Requester *string `json:"requester,omitempty" azure:"ro"` + + // READ-ONLY; The requester object id + RequesterObjectID *string `json:"requesterObjectId,omitempty" azure:"ro"` +} + +// ClientGetOptions contains the optional parameters for the Client.Get method. +type ClientGetOptions struct { + // placeholder for future optional parameters +} + +// ClientListAllOptions contains the optional parameters for the Client.NewListAllPager method. +type ClientListAllOptions struct { + // placeholder for future optional parameters +} + +// ClientListOptions contains the optional parameters for the Client.NewListPager method. +type ClientListOptions struct { + // placeholder for future optional parameters +} + +// ClientRegisterOptions contains the optional parameters for the Client.Register method. +type ClientRegisterOptions struct { + // placeholder for future optional parameters +} + +// ClientUnregisterOptions contains the optional parameters for the Client.Unregister method. +type ClientUnregisterOptions struct { + // placeholder for future optional parameters +} + +// ErrorDefinition - Error definition. +type ErrorDefinition struct { + // Internal error details. + Details []*ErrorDefinition `json:"details,omitempty"` + + // READ-ONLY; Service specific error code which serves as the substatus for the HTTP error code. + Code *string `json:"code,omitempty" azure:"ro"` + + // READ-ONLY; Description of the error. + Message *string `json:"message,omitempty" azure:"ro"` +} + +// ErrorResponse - Error response indicates that the service is not able to process the incoming request. +type ErrorResponse struct { + // The error details. + Error *ErrorDefinition `json:"error,omitempty"` +} + +// FeatureClientListOperationsOptions contains the optional parameters for the FeatureClient.NewListOperationsPager method. +type FeatureClientListOperationsOptions struct { + // placeholder for future optional parameters +} + +// FeatureOperationsListResult - List of previewed features. +type FeatureOperationsListResult struct { + // The URL to use for getting the next set of results. + NextLink *string `json:"nextLink,omitempty"` + + // The array of features. + Value []*FeatureResult `json:"value,omitempty"` +} + +// FeatureProperties - Information about feature. +type FeatureProperties struct { + // The registration state of the feature for the subscription. + State *string `json:"state,omitempty"` +} + +// FeatureResult - Previewed feature information. +type FeatureResult struct { + // The resource ID of the feature. + ID *string `json:"id,omitempty"` + + // The name of the feature. + Name *string `json:"name,omitempty"` + + // Properties of the previewed feature. + Properties *FeatureProperties `json:"properties,omitempty"` + + // The resource type of the feature. + Type *string `json:"type,omitempty"` +} + +// Operation - Microsoft.Features operation +type Operation struct { + // The object that represents the operation. + Display *OperationDisplay `json:"display,omitempty"` + + // Operation name: {provider}/{resource}/{operation} + Name *string `json:"name,omitempty"` +} + +// OperationDisplay - The object that represents the operation. +type OperationDisplay struct { + // Operation type: Read, write, delete, etc. + Operation *string `json:"operation,omitempty"` + + // Service provider: Microsoft.Features + Provider *string `json:"provider,omitempty"` + + // Resource on which the operation is performed: Profile, endpoint, etc. + Resource *string `json:"resource,omitempty"` +} + +// OperationListResult - Result of the request to list Microsoft.Features operations. It contains a list of operations and +// a URL link to get the next set of results. +type OperationListResult struct { + // URL to get the next set of operation list results if there are any. + NextLink *string `json:"nextLink,omitempty"` + + // List of Microsoft.Features operations. + Value []*Operation `json:"value,omitempty"` +} + +// ProxyResource - An Azure proxy resource. +type ProxyResource struct { + // READ-ONLY; Azure resource Id. + ID *string `json:"id,omitempty" azure:"ro"` + + // READ-ONLY; Azure resource name. + Name *string `json:"name,omitempty" azure:"ro"` + + // READ-ONLY; Azure resource type. + Type *string `json:"type,omitempty" azure:"ro"` +} + +// SubscriptionFeatureRegistration - Subscription feature registration details +type SubscriptionFeatureRegistration struct { + Properties *SubscriptionFeatureRegistrationProperties `json:"properties,omitempty"` + + // READ-ONLY; Azure resource Id. + ID *string `json:"id,omitempty" azure:"ro"` + + // READ-ONLY; Azure resource name. + Name *string `json:"name,omitempty" azure:"ro"` + + // READ-ONLY; Azure resource type. + Type *string `json:"type,omitempty" azure:"ro"` +} + +// SubscriptionFeatureRegistrationList - The list of subscription feature registrations. +type SubscriptionFeatureRegistrationList struct { + // The link used to get the next page of subscription feature registrations list. + NextLink *string `json:"nextLink,omitempty"` + + // The list of subscription feature registrations. + Value []*SubscriptionFeatureRegistration `json:"value,omitempty"` +} + +type SubscriptionFeatureRegistrationProperties struct { + // Authorization Profile + AuthorizationProfile *AuthorizationProfile `json:"authorizationProfile,omitempty"` + + // The feature description. + Description *string `json:"description,omitempty"` + + // Key-value pairs for meta data. + Metadata map[string]*string `json:"metadata,omitempty"` + + // Indicates whether feature should be displayed in Portal. + ShouldFeatureDisplayInPortal *bool `json:"shouldFeatureDisplayInPortal,omitempty"` + + // The state. + State *SubscriptionFeatureRegistrationState `json:"state,omitempty"` + + // READ-ONLY; The feature approval type. + ApprovalType *SubscriptionFeatureRegistrationApprovalType `json:"approvalType,omitempty" azure:"ro"` + + // READ-ONLY; The featureDisplayName. + DisplayName *string `json:"displayName,omitempty" azure:"ro"` + + // READ-ONLY; The feature documentation link. + DocumentationLink *string `json:"documentationLink,omitempty" azure:"ro"` + + // READ-ONLY; The featureName. + FeatureName *string `json:"featureName,omitempty" azure:"ro"` + + // READ-ONLY; The providerNamespace. + ProviderNamespace *string `json:"providerNamespace,omitempty" azure:"ro"` + + // READ-ONLY; The feature registration date. + RegistrationDate *time.Time `json:"registrationDate,omitempty" azure:"ro"` + + // READ-ONLY; The feature release date. + ReleaseDate *time.Time `json:"releaseDate,omitempty" azure:"ro"` + + // READ-ONLY; The subscriptionId. + SubscriptionID *string `json:"subscriptionId,omitempty" azure:"ro"` + + // READ-ONLY; The tenantId. + TenantID *string `json:"tenantId,omitempty" azure:"ro"` +} + +// SubscriptionFeatureRegistrationsClientCreateOrUpdateOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.CreateOrUpdate +// method. +type SubscriptionFeatureRegistrationsClientCreateOrUpdateOptions struct { + // Subscription Feature Registration Type details. + SubscriptionFeatureRegistrationType *SubscriptionFeatureRegistration +} + +// SubscriptionFeatureRegistrationsClientDeleteOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.Delete +// method. +type SubscriptionFeatureRegistrationsClientDeleteOptions struct { + // placeholder for future optional parameters +} + +// SubscriptionFeatureRegistrationsClientGetOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.Get +// method. +type SubscriptionFeatureRegistrationsClientGetOptions struct { + // placeholder for future optional parameters +} + +// SubscriptionFeatureRegistrationsClientListAllBySubscriptionOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.NewListAllBySubscriptionPager +// method. +type SubscriptionFeatureRegistrationsClientListAllBySubscriptionOptions struct { + // placeholder for future optional parameters +} + +// SubscriptionFeatureRegistrationsClientListBySubscriptionOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.NewListBySubscriptionPager +// method. +type SubscriptionFeatureRegistrationsClientListBySubscriptionOptions struct { + // placeholder for future optional parameters +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models_serde.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models_serde.go new file mode 100644 index 00000000000..8dc3c194867 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/models_serde.go @@ -0,0 +1,520 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" +) + +// MarshalJSON implements the json.Marshaller interface for type AuthorizationProfile. +func (a AuthorizationProfile) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateTimeRFC3339(objectMap, "approvedTime", a.ApprovedTime) + populate(objectMap, "approver", a.Approver) + populateTimeRFC3339(objectMap, "requestedTime", a.RequestedTime) + populate(objectMap, "requester", a.Requester) + populate(objectMap, "requesterObjectId", a.RequesterObjectID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AuthorizationProfile. +func (a *AuthorizationProfile) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "approvedTime": + err = unpopulateTimeRFC3339(val, "ApprovedTime", &a.ApprovedTime) + delete(rawMsg, key) + case "approver": + err = unpopulate(val, "Approver", &a.Approver) + delete(rawMsg, key) + case "requestedTime": + err = unpopulateTimeRFC3339(val, "RequestedTime", &a.RequestedTime) + delete(rawMsg, key) + case "requester": + err = unpopulate(val, "Requester", &a.Requester) + delete(rawMsg, key) + case "requesterObjectId": + err = unpopulate(val, "RequesterObjectID", &a.RequesterObjectID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ErrorDefinition. +func (e ErrorDefinition) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", e.Code) + populate(objectMap, "details", e.Details) + populate(objectMap, "message", e.Message) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorDefinition. +func (e *ErrorDefinition) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &e.Code) + delete(rawMsg, key) + case "details": + err = unpopulate(val, "Details", &e.Details) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &e.Message) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ErrorResponse. +func (e ErrorResponse) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", e.Error) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponse. +func (e *ErrorResponse) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &e.Error) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type FeatureOperationsListResult. +func (f FeatureOperationsListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", f.NextLink) + populate(objectMap, "value", f.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type FeatureOperationsListResult. +func (f *FeatureOperationsListResult) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &f.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &f.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type FeatureProperties. +func (f FeatureProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "state", f.State) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type FeatureProperties. +func (f *FeatureProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "state": + err = unpopulate(val, "State", &f.State) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type FeatureResult. +func (f FeatureResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", f.ID) + populate(objectMap, "name", f.Name) + populate(objectMap, "properties", f.Properties) + populate(objectMap, "type", f.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type FeatureResult. +func (f *FeatureResult) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &f.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &f.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &f.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &f.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Operation. +func (o Operation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "display", o.Display) + populate(objectMap, "name", o.Name) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Operation. +func (o *Operation) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "display": + err = unpopulate(val, "Display", &o.Display) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &o.Name) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OperationDisplay. +func (o OperationDisplay) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "operation", o.Operation) + populate(objectMap, "provider", o.Provider) + populate(objectMap, "resource", o.Resource) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OperationDisplay. +func (o *OperationDisplay) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "operation": + err = unpopulate(val, "Operation", &o.Operation) + delete(rawMsg, key) + case "provider": + err = unpopulate(val, "Provider", &o.Provider) + delete(rawMsg, key) + case "resource": + err = unpopulate(val, "Resource", &o.Resource) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OperationListResult. +func (o OperationListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", o.NextLink) + populate(objectMap, "value", o.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OperationListResult. +func (o *OperationListResult) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &o.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &o.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProxyResource. +func (p ProxyResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", p.ID) + populate(objectMap, "name", p.Name) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProxyResource. +func (p *ProxyResource) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &p.Name) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SubscriptionFeatureRegistration. +func (s SubscriptionFeatureRegistration) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", s.ID) + populate(objectMap, "name", s.Name) + populate(objectMap, "properties", s.Properties) + populate(objectMap, "type", s.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SubscriptionFeatureRegistration. +func (s *SubscriptionFeatureRegistration) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &s.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &s.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &s.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &s.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SubscriptionFeatureRegistrationList. +func (s SubscriptionFeatureRegistrationList) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", s.NextLink) + populate(objectMap, "value", s.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SubscriptionFeatureRegistrationList. +func (s *SubscriptionFeatureRegistrationList) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &s.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &s.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SubscriptionFeatureRegistrationProperties. +func (s SubscriptionFeatureRegistrationProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "approvalType", s.ApprovalType) + populate(objectMap, "authorizationProfile", s.AuthorizationProfile) + populate(objectMap, "description", s.Description) + populate(objectMap, "displayName", s.DisplayName) + populate(objectMap, "documentationLink", s.DocumentationLink) + populate(objectMap, "featureName", s.FeatureName) + populate(objectMap, "metadata", s.Metadata) + populate(objectMap, "providerNamespace", s.ProviderNamespace) + populateTimeRFC3339(objectMap, "registrationDate", s.RegistrationDate) + populateTimeRFC3339(objectMap, "releaseDate", s.ReleaseDate) + populate(objectMap, "shouldFeatureDisplayInPortal", s.ShouldFeatureDisplayInPortal) + populate(objectMap, "state", s.State) + populate(objectMap, "subscriptionId", s.SubscriptionID) + populate(objectMap, "tenantId", s.TenantID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SubscriptionFeatureRegistrationProperties. +func (s *SubscriptionFeatureRegistrationProperties) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "approvalType": + err = unpopulate(val, "ApprovalType", &s.ApprovalType) + delete(rawMsg, key) + case "authorizationProfile": + err = unpopulate(val, "AuthorizationProfile", &s.AuthorizationProfile) + delete(rawMsg, key) + case "description": + err = unpopulate(val, "Description", &s.Description) + delete(rawMsg, key) + case "displayName": + err = unpopulate(val, "DisplayName", &s.DisplayName) + delete(rawMsg, key) + case "documentationLink": + err = unpopulate(val, "DocumentationLink", &s.DocumentationLink) + delete(rawMsg, key) + case "featureName": + err = unpopulate(val, "FeatureName", &s.FeatureName) + delete(rawMsg, key) + case "metadata": + err = unpopulate(val, "Metadata", &s.Metadata) + delete(rawMsg, key) + case "providerNamespace": + err = unpopulate(val, "ProviderNamespace", &s.ProviderNamespace) + delete(rawMsg, key) + case "registrationDate": + err = unpopulateTimeRFC3339(val, "RegistrationDate", &s.RegistrationDate) + delete(rawMsg, key) + case "releaseDate": + err = unpopulateTimeRFC3339(val, "ReleaseDate", &s.ReleaseDate) + delete(rawMsg, key) + case "shouldFeatureDisplayInPortal": + err = unpopulate(val, "ShouldFeatureDisplayInPortal", &s.ShouldFeatureDisplayInPortal) + delete(rawMsg, key) + case "state": + err = unpopulate(val, "State", &s.State) + delete(rawMsg, key) + case "subscriptionId": + err = unpopulate(val, "SubscriptionID", &s.SubscriptionID) + delete(rawMsg, key) + case "tenantId": + err = unpopulate(val, "TenantID", &s.TenantID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +func populate(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else if !reflect.ValueOf(v).IsNil() { + m[k] = v + } +} + +func unpopulate(data json.RawMessage, fn string, v any) error { + if data == nil { + return nil + } + if err := json.Unmarshal(data, v); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/response_types.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/response_types.go new file mode 100644 index 00000000000..ab54c7db036 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/response_types.go @@ -0,0 +1,65 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +// ClientGetResponse contains the response from method Client.Get. +type ClientGetResponse struct { + FeatureResult +} + +// ClientListAllResponse contains the response from method Client.NewListAllPager. +type ClientListAllResponse struct { + FeatureOperationsListResult +} + +// ClientListResponse contains the response from method Client.NewListPager. +type ClientListResponse struct { + FeatureOperationsListResult +} + +// ClientRegisterResponse contains the response from method Client.Register. +type ClientRegisterResponse struct { + FeatureResult +} + +// ClientUnregisterResponse contains the response from method Client.Unregister. +type ClientUnregisterResponse struct { + FeatureResult +} + +// FeatureClientListOperationsResponse contains the response from method FeatureClient.NewListOperationsPager. +type FeatureClientListOperationsResponse struct { + OperationListResult +} + +// SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse contains the response from method SubscriptionFeatureRegistrationsClient.CreateOrUpdate. +type SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse struct { + SubscriptionFeatureRegistration +} + +// SubscriptionFeatureRegistrationsClientDeleteResponse contains the response from method SubscriptionFeatureRegistrationsClient.Delete. +type SubscriptionFeatureRegistrationsClientDeleteResponse struct { + // placeholder for future response values +} + +// SubscriptionFeatureRegistrationsClientGetResponse contains the response from method SubscriptionFeatureRegistrationsClient.Get. +type SubscriptionFeatureRegistrationsClientGetResponse struct { + SubscriptionFeatureRegistration +} + +// SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse contains the response from method SubscriptionFeatureRegistrationsClient.NewListAllBySubscriptionPager. +type SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse struct { + SubscriptionFeatureRegistrationList +} + +// SubscriptionFeatureRegistrationsClientListBySubscriptionResponse contains the response from method SubscriptionFeatureRegistrationsClient.NewListBySubscriptionPager. +type SubscriptionFeatureRegistrationsClientListBySubscriptionResponse struct { + SubscriptionFeatureRegistrationList +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/subscriptionfeatureregistrations_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/subscriptionfeatureregistrations_client.go new file mode 100644 index 00000000000..00c3ee6efce --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/subscriptionfeatureregistrations_client.go @@ -0,0 +1,338 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import ( + "context" + "errors" + "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/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// SubscriptionFeatureRegistrationsClient contains the methods for the SubscriptionFeatureRegistrations group. +// Don't use this type directly, use NewSubscriptionFeatureRegistrationsClient() instead. +type SubscriptionFeatureRegistrationsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewSubscriptionFeatureRegistrationsClient creates a new instance of SubscriptionFeatureRegistrationsClient with the specified values. +// - subscriptionID - The Azure subscription ID. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewSubscriptionFeatureRegistrationsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*SubscriptionFeatureRegistrationsClient, error) { + cl, err := arm.NewClient(moduleName+".SubscriptionFeatureRegistrationsClient", moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &SubscriptionFeatureRegistrationsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// CreateOrUpdate - Create or update a feature registration. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - providerNamespace - The provider namespace. +// - featureName - The feature name. +// - options - SubscriptionFeatureRegistrationsClientCreateOrUpdateOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.CreateOrUpdate +// method. +func (client *SubscriptionFeatureRegistrationsClient) CreateOrUpdate(ctx context.Context, providerNamespace string, featureName string, options *SubscriptionFeatureRegistrationsClientCreateOrUpdateOptions) (SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse, error) { + req, err := client.createOrUpdateCreateRequest(ctx, providerNamespace, featureName, options) + if err != nil { + return SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse{}, runtime.NewResponseError(resp) + } + return client.createOrUpdateHandleResponse(resp) +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *SubscriptionFeatureRegistrationsClient) createOrUpdateCreateRequest(ctx context.Context, providerNamespace string, featureName string, options *SubscriptionFeatureRegistrationsClientCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/featureProviders/{providerNamespace}/subscriptionFeatureRegistrations/{featureName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if providerNamespace == "" { + return nil, errors.New("parameter providerNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{providerNamespace}", url.PathEscape(providerNamespace)) + if featureName == "" { + return nil, errors.New("parameter featureName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{featureName}", url.PathEscape(featureName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if options != nil && options.SubscriptionFeatureRegistrationType != nil { + return req, runtime.MarshalAsJSON(req, *options.SubscriptionFeatureRegistrationType) + } + return req, nil +} + +// createOrUpdateHandleResponse handles the CreateOrUpdate response. +func (client *SubscriptionFeatureRegistrationsClient) createOrUpdateHandleResponse(resp *http.Response) (SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse, error) { + result := SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.SubscriptionFeatureRegistration); err != nil { + return SubscriptionFeatureRegistrationsClientCreateOrUpdateResponse{}, err + } + return result, nil +} + +// Delete - Deletes a feature registration +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - providerNamespace - The provider namespace. +// - featureName - The feature name. +// - options - SubscriptionFeatureRegistrationsClientDeleteOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.Delete +// method. +func (client *SubscriptionFeatureRegistrationsClient) Delete(ctx context.Context, providerNamespace string, featureName string, options *SubscriptionFeatureRegistrationsClientDeleteOptions) (SubscriptionFeatureRegistrationsClientDeleteResponse, error) { + req, err := client.deleteCreateRequest(ctx, providerNamespace, featureName, options) + if err != nil { + return SubscriptionFeatureRegistrationsClientDeleteResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return SubscriptionFeatureRegistrationsClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusNoContent) { + return SubscriptionFeatureRegistrationsClientDeleteResponse{}, runtime.NewResponseError(resp) + } + return SubscriptionFeatureRegistrationsClientDeleteResponse{}, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *SubscriptionFeatureRegistrationsClient) deleteCreateRequest(ctx context.Context, providerNamespace string, featureName string, options *SubscriptionFeatureRegistrationsClientDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/featureProviders/{providerNamespace}/subscriptionFeatureRegistrations/{featureName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if providerNamespace == "" { + return nil, errors.New("parameter providerNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{providerNamespace}", url.PathEscape(providerNamespace)) + if featureName == "" { + return nil, errors.New("parameter featureName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{featureName}", url.PathEscape(featureName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Get - Returns a feature registration +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-07-01 +// - providerNamespace - The provider namespace. +// - featureName - The feature name. +// - options - SubscriptionFeatureRegistrationsClientGetOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.Get +// method. +func (client *SubscriptionFeatureRegistrationsClient) Get(ctx context.Context, providerNamespace string, featureName string, options *SubscriptionFeatureRegistrationsClientGetOptions) (SubscriptionFeatureRegistrationsClientGetResponse, error) { + req, err := client.getCreateRequest(ctx, providerNamespace, featureName, options) + if err != nil { + return SubscriptionFeatureRegistrationsClientGetResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return SubscriptionFeatureRegistrationsClientGetResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return SubscriptionFeatureRegistrationsClientGetResponse{}, runtime.NewResponseError(resp) + } + return client.getHandleResponse(resp) +} + +// getCreateRequest creates the Get request. +func (client *SubscriptionFeatureRegistrationsClient) getCreateRequest(ctx context.Context, providerNamespace string, featureName string, options *SubscriptionFeatureRegistrationsClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/featureProviders/{providerNamespace}/subscriptionFeatureRegistrations/{featureName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if providerNamespace == "" { + return nil, errors.New("parameter providerNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{providerNamespace}", url.PathEscape(providerNamespace)) + if featureName == "" { + return nil, errors.New("parameter featureName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{featureName}", url.PathEscape(featureName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *SubscriptionFeatureRegistrationsClient) getHandleResponse(resp *http.Response) (SubscriptionFeatureRegistrationsClientGetResponse, error) { + result := SubscriptionFeatureRegistrationsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.SubscriptionFeatureRegistration); err != nil { + return SubscriptionFeatureRegistrationsClientGetResponse{}, err + } + return result, nil +} + +// NewListAllBySubscriptionPager - Returns subscription feature registrations for given subscription. +// +// Generated from API version 2021-07-01 +// - options - SubscriptionFeatureRegistrationsClientListAllBySubscriptionOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.NewListAllBySubscriptionPager +// method. +func (client *SubscriptionFeatureRegistrationsClient) NewListAllBySubscriptionPager(options *SubscriptionFeatureRegistrationsClientListAllBySubscriptionOptions) *runtime.Pager[SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse] { + return runtime.NewPager(runtime.PagingHandler[SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse]{ + More: func(page SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse) (SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse, error) { + var req *policy.Request + var err error + if page == nil { + req, err = client.listAllBySubscriptionCreateRequest(ctx, options) + } else { + req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink) + } + if err != nil { + return SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse{}, runtime.NewResponseError(resp) + } + return client.listAllBySubscriptionHandleResponse(resp) + }, + }) +} + +// listAllBySubscriptionCreateRequest creates the ListAllBySubscription request. +func (client *SubscriptionFeatureRegistrationsClient) listAllBySubscriptionCreateRequest(ctx context.Context, options *SubscriptionFeatureRegistrationsClientListAllBySubscriptionOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/subscriptionFeatureRegistrations" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAllBySubscriptionHandleResponse handles the ListAllBySubscription response. +func (client *SubscriptionFeatureRegistrationsClient) listAllBySubscriptionHandleResponse(resp *http.Response) (SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse, error) { + result := SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.SubscriptionFeatureRegistrationList); err != nil { + return SubscriptionFeatureRegistrationsClientListAllBySubscriptionResponse{}, err + } + return result, nil +} + +// NewListBySubscriptionPager - Returns subscription feature registrations for given subscription and provider namespace. +// +// Generated from API version 2021-07-01 +// - providerNamespace - The provider namespace. +// - options - SubscriptionFeatureRegistrationsClientListBySubscriptionOptions contains the optional parameters for the SubscriptionFeatureRegistrationsClient.NewListBySubscriptionPager +// method. +func (client *SubscriptionFeatureRegistrationsClient) NewListBySubscriptionPager(providerNamespace string, options *SubscriptionFeatureRegistrationsClientListBySubscriptionOptions) *runtime.Pager[SubscriptionFeatureRegistrationsClientListBySubscriptionResponse] { + return runtime.NewPager(runtime.PagingHandler[SubscriptionFeatureRegistrationsClientListBySubscriptionResponse]{ + More: func(page SubscriptionFeatureRegistrationsClientListBySubscriptionResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *SubscriptionFeatureRegistrationsClientListBySubscriptionResponse) (SubscriptionFeatureRegistrationsClientListBySubscriptionResponse, error) { + var req *policy.Request + var err error + if page == nil { + req, err = client.listBySubscriptionCreateRequest(ctx, providerNamespace, options) + } else { + req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink) + } + if err != nil { + return SubscriptionFeatureRegistrationsClientListBySubscriptionResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return SubscriptionFeatureRegistrationsClientListBySubscriptionResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return SubscriptionFeatureRegistrationsClientListBySubscriptionResponse{}, runtime.NewResponseError(resp) + } + return client.listBySubscriptionHandleResponse(resp) + }, + }) +} + +// listBySubscriptionCreateRequest creates the ListBySubscription request. +func (client *SubscriptionFeatureRegistrationsClient) listBySubscriptionCreateRequest(ctx context.Context, providerNamespace string, options *SubscriptionFeatureRegistrationsClientListBySubscriptionOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Features/featureProviders/{providerNamespace}/subscriptionFeatureRegistrations" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if providerNamespace == "" { + return nil, errors.New("parameter providerNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{providerNamespace}", url.PathEscape(providerNamespace)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listBySubscriptionHandleResponse handles the ListBySubscription response. +func (client *SubscriptionFeatureRegistrationsClient) listBySubscriptionHandleResponse(resp *http.Response) (SubscriptionFeatureRegistrationsClientListBySubscriptionResponse, error) { + result := SubscriptionFeatureRegistrationsClientListBySubscriptionResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.SubscriptionFeatureRegistrationList); err != nil { + return SubscriptionFeatureRegistrationsClientListBySubscriptionResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/time_rfc3339.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/time_rfc3339.go new file mode 100644 index 00000000000..95a9f1c0cd4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures/time_rfc3339.go @@ -0,0 +1,87 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package armfeatures + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" + "regexp" + "strings" + "time" +) + +const ( + utcLayoutJSON = `"2006-01-02T15:04:05.999999999"` + utcLayout = "2006-01-02T15:04:05.999999999" + rfc3339JSON = `"` + time.RFC3339Nano + `"` +) + +// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. +var tzOffsetRegex = regexp.MustCompile(`(Z|z|\+|-)(\d+:\d+)*"*$`) + +type timeRFC3339 time.Time + +func (t timeRFC3339) MarshalJSON() (json []byte, err error) { + tt := time.Time(t) + return tt.MarshalJSON() +} + +func (t timeRFC3339) MarshalText() (text []byte, err error) { + tt := time.Time(t) + return tt.MarshalText() +} + +func (t *timeRFC3339) UnmarshalJSON(data []byte) error { + layout := utcLayoutJSON + if tzOffsetRegex.Match(data) { + layout = rfc3339JSON + } + return t.Parse(layout, string(data)) +} + +func (t *timeRFC3339) UnmarshalText(data []byte) (err error) { + layout := utcLayout + if tzOffsetRegex.Match(data) { + layout = time.RFC3339Nano + } + return t.Parse(layout, string(data)) +} + +func (t *timeRFC3339) Parse(layout, value string) error { + p, err := time.Parse(layout, strings.ToUpper(value)) + *t = timeRFC3339(p) + return err +} + +func populateTimeRFC3339(m map[string]any, k string, t *time.Time) { + if t == nil { + return + } else if azcore.IsNullValue(t) { + m[k] = nil + return + } else if reflect.ValueOf(t).IsNil() { + return + } + m[k] = (*timeRFC3339)(t) +} + +func unpopulateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error { + if data == nil || strings.EqualFold(string(data), "null") { + return nil + } + var aux timeRFC3339 + if err := json.Unmarshal(data, &aux); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + *t = (*time.Time)(&aux) + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8b4bb8aeaa9..746a9a0e7c5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -19,6 +19,10 @@ github.com/Azure/azure-sdk-for-go/version # github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 ## explicit; go 1.18 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/arm/internal/resource +github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy +github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log @@ -45,6 +49,9 @@ github.com/Azure/azure-sdk-for-go/sdk/internal/log github.com/Azure/azure-sdk-for-go/sdk/internal/poller github.com/Azure/azure-sdk-for-go/sdk/internal/temporal github.com/Azure/azure-sdk-for-go/sdk/internal/uuid +# github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures v1.1.0 +## explicit; go 1.18 +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armfeatures # github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 ## explicit; go 1.16 github.com/Azure/go-ansiterm