Skip to content

Commit

Permalink
refactor for resourceprovider changes
Browse files Browse the repository at this point in the history
add enums for resouceprovider sets
add helper function GetResourceProvidersSet
  • Loading branch information
jackofallops committed Jul 12, 2024
1 parent 24ce583 commit ecff80a
Show file tree
Hide file tree
Showing 26 changed files with 1,146 additions and 63 deletions.
31 changes: 20 additions & 11 deletions internal/provider/framework/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package framework

import (
"context"
"fmt"
"os"
"time"

Expand Down Expand Up @@ -116,7 +115,7 @@ func (p *ProviderConfig) Load(ctx context.Context, data *ProviderModel, tfVersio
p.clientBuilder.PartnerID = partnerId
p.clientBuilder.DisableCorrelationRequestID = getEnvBoolOrDefault(data.DisableCorrelationRequestId, "ARM_DISABLE_CORRELATION_REQUEST_ID", false)
p.clientBuilder.DisableTerraformPartnerID = getEnvBoolOrDefault(data.DisableTerraformPartnerId, "ARM_DISABLE_TERRAFORM_PARTNER_ID", false)
p.clientBuilder.SkipProviderRegistration = getEnvBoolOrDefault(data.SkipProviderRegistration, "ARM_SKIP_PROVIDER_REGISTRATION", false)
//p.clientBuilder.SkipProviderRegistration = getEnvBoolOrDefault(data.SkipProviderRegistration, "ARM_SKIP_PROVIDER_REGISTRATION", false)

Check failure on line 118 in internal/provider/framework/config.go

View workflow job for this annotation

GitHub Actions / golint

commentFormatting: put a space between `//` and comment text (gocritic)
p.clientBuilder.StorageUseAzureAD = getEnvBoolOrDefault(data.StorageUseAzureAD, "ARM_STORAGE_USE_AZUREAD", false)

f := providerfeatures.UserFeatures{}
Expand Down Expand Up @@ -480,17 +479,27 @@ func (p *ProviderConfig) Load(ctx context.Context, data *ProviderModel, tfVersio

client.StopContext = ctx

if !p.clientBuilder.SkipProviderRegistration {
subscriptionId := commonids.NewSubscriptionID(client.Account.SubscriptionId)
requiredResourceProviders := resourceproviders.Required()
ctx2, cancel := context.WithTimeout(ctx, 30*time.Minute)
defer cancel()

if err := resourceproviders.EnsureRegistered(ctx2, client.Resource.ResourceProvidersClient, subscriptionId, requiredResourceProviders); err != nil {
diags.Append(diag.NewErrorDiagnostic("resource provider registration failed", fmt.Sprintf(provider.ResourceProviderRegistrationErrorFmt, err)))
return
resourceProviderRegistrationSet := getEnvStringOrDefault(data.ResourceProviderRegistrations, "ARM_RESOURCE_PROVIDER_REGISTRATIONS", "legacy")
requiredResourceProviders, err := resourceproviders.GetResourceProvidersSet(resourceProviderRegistrationSet)

Check failure on line 483 in internal/provider/framework/config.go

View workflow job for this annotation

GitHub Actions / golint

SA4006: this value of `err` is never used (staticcheck)
additionalResourceProvidersToRegister := make([]string, 0)
if !data.ResourceProvidersToRegister.IsNull() {
data.ResourceProvidersToRegister.ElementsAs(ctx, &additionalResourceProvidersToRegister, false)
if len(additionalResourceProvidersToRegister) > 0 {
additionalProviders := make(resourceproviders.ResourceProviders)
for _, rp := range additionalResourceProvidersToRegister {
additionalProviders.Add(rp)
}
}
}

subscriptionId := commonids.NewSubscriptionID(client.Account.SubscriptionId)
ctx2, cancel := context.WithTimeout(ctx, 30*time.Minute)
defer cancel()

if err = resourceproviders.EnsureRegistered(ctx2, client.Resource.ResourceProvidersClient, subscriptionId, requiredResourceProviders); err != nil {
diags.AddError("registering resource providers", err.Error())
return
}

p.Client = client
}
4 changes: 2 additions & 2 deletions internal/provider/framework/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func TestProviderConfig_LoadDefault(t *testing.T) {
_ = os.Setenv("ARM_PROVIDER_ENHANCED_VALIDATION", "false")

testData := &ProviderModel{
SkipProviderRegistration: types.BoolValue(true), // We don't want this test to modify the configured sub at all
Features: defaultFeaturesList(),
ResourceProviderRegistrations: types.StringValue("none"),
Features: defaultFeaturesList(),
}

testConfig.Load(context.Background(), testData, "unittest", &diag.Diagnostics{})
Expand Down
55 changes: 28 additions & 27 deletions internal/provider/framework/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,34 @@ import (
)

type ProviderModel struct {
SubscriptionId types.String `tfsdk:"subscription_id"`
ClientId types.String `tfsdk:"client_id"`
ClientIdFilePath types.String `tfsdk:"client_id_file_path"`
TenantId types.String `tfsdk:"tenant_id"`
AuxiliaryTenantIds types.List `tfsdk:"auxiliary_tenant_ids"`
Environment types.String `tfsdk:"environment"`
MetaDataHost types.String `tfsdk:"metadata_host"`
ClientCertificate types.String `tfsdk:"client_certificate"`
ClientCertificatePath types.String `tfsdk:"client_certificate_path"`
ClientCertificatePassword types.String `tfsdk:"client_certificate_password"`
ClientSecret types.String `tfsdk:"client_secret"`
ClientSecretFilePath types.String `tfsdk:"client_secret_file_path"`
OIDCRequestToken types.String `tfsdk:"oidc_request_token"`
OIDCRequestURL types.String `tfsdk:"oidc_request_url"`
OIDCToken types.String `tfsdk:"oidc_token"`
OIDCTokenFilePath types.String `tfsdk:"oidc_token_file_path"`
UseOIDC types.Bool `tfsdk:"use_oidc"`
UseMSI types.Bool `tfsdk:"use_msi"`
MSIEndpoint types.String `tfsdk:"msi_endpoint"`
UseCLI types.Bool `tfsdk:"use_cli"`
UseAKSWorkloadIdentity types.Bool `tfsdk:"use_aks_workload_identity"`
PartnerId types.String `tfsdk:"partner_id"`
DisableCorrelationRequestId types.Bool `tfsdk:"disable_correlation_request_id"`
DisableTerraformPartnerId types.Bool `tfsdk:"disable_terraform_partner_id"`
SkipProviderRegistration types.Bool `tfsdk:"skip_provider_registration"`
StorageUseAzureAD types.Bool `tfsdk:"storage_use_azuread"`
Features types.List `tfsdk:"features"`
SubscriptionId types.String `tfsdk:"subscription_id"`
ClientId types.String `tfsdk:"client_id"`
ClientIdFilePath types.String `tfsdk:"client_id_file_path"`
TenantId types.String `tfsdk:"tenant_id"`
AuxiliaryTenantIds types.List `tfsdk:"auxiliary_tenant_ids"`
Environment types.String `tfsdk:"environment"`
MetaDataHost types.String `tfsdk:"metadata_host"`
ClientCertificate types.String `tfsdk:"client_certificate"`
ClientCertificatePath types.String `tfsdk:"client_certificate_path"`
ClientCertificatePassword types.String `tfsdk:"client_certificate_password"`
ClientSecret types.String `tfsdk:"client_secret"`
ClientSecretFilePath types.String `tfsdk:"client_secret_file_path"`
OIDCRequestToken types.String `tfsdk:"oidc_request_token"`
OIDCRequestURL types.String `tfsdk:"oidc_request_url"`
OIDCToken types.String `tfsdk:"oidc_token"`
OIDCTokenFilePath types.String `tfsdk:"oidc_token_file_path"`
UseOIDC types.Bool `tfsdk:"use_oidc"`
UseMSI types.Bool `tfsdk:"use_msi"`
MSIEndpoint types.String `tfsdk:"msi_endpoint"`
UseCLI types.Bool `tfsdk:"use_cli"`
UseAKSWorkloadIdentity types.Bool `tfsdk:"use_aks_workload_identity"`
PartnerId types.String `tfsdk:"partner_id"`
DisableCorrelationRequestId types.Bool `tfsdk:"disable_correlation_request_id"`
DisableTerraformPartnerId types.Bool `tfsdk:"disable_terraform_partner_id"`
StorageUseAzureAD types.Bool `tfsdk:"storage_use_azuread"`
Features types.List `tfsdk:"features"`
ResourceProviderRegistrations types.String `tfsdk:"resource_provider_registrations"`
ResourceProvidersToRegister types.List `tfsdk:"resource_providers_to_register"`
}

type Features struct {
Expand Down
27 changes: 27 additions & 0 deletions internal/provider/framework/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package framework

import (
"context"

Check failure on line 4 in internal/provider/framework/provider.go

View workflow job for this annotation

GitHub Actions / golint

File is not `goimports`-ed (goimports)
"github.com/hashicorp/terraform-provider-azurerm/internal/resourceproviders"

"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/function"
"github.com/hashicorp/terraform-plugin-framework/provider"
Expand Down Expand Up @@ -186,6 +188,31 @@ func (p *azureRmFrameworkProvider) Schema(_ context.Context, _ provider.SchemaRe
//DefaultFunc: schema.EnvDefaultFunc("ARM_STORAGE_USE_AZUREAD", false),
Description: "Should the AzureRM Provider use AzureAD to access the Storage Data Plane API's?",
},

"resource_provider_registrations": schema.StringAttribute{
Optional: true,
Description: "The set of Resource Providers which should be automatically registered for the subscription.",
MarkdownDescription: "The set of Resource Providers which should be automatically registered for the subscription.",
Validators: []validator.String{
stringvalidator.OneOf(
resourceproviders.ProviderRegistrationsNone,
resourceproviders.ProviderRegistrationsLegacy,
resourceproviders.ProviderRegistrationsCore,
resourceproviders.ProviderRegistrationsExtended,
resourceproviders.ProviderRegistrationsAll,
),
},
},

"resource_providers_to_register": schema.ListAttribute{
ElementType: types.StringType,
Optional: true,
Description: "A list of Resource Providers to explicitly register for the subscription, in addition to those specified by the `resource_provider_registrations` property.",
MarkdownDescription: "A list of Resource Providers to explicitly register for the subscription, in addition to those specified by the `resource_provider_registrations` property.",
Validators: []validator.List{
// TODO - Need to port over the pluginSDK wrapper for validators to use the legacy one for now.
},
},
},

Blocks: map[string]schema.Block{
Expand Down
35 changes: 12 additions & 23 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,14 +325,14 @@ func azureProvider(supportLegacyTestSuite bool) *schema.Provider {
"resource_provider_registrations": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("ARM_RESOURCE_PROVIDER_REGISTRATIONS", "legacy"),
DefaultFunc: schema.EnvDefaultFunc("ARM_RESOURCE_PROVIDER_REGISTRATIONS", resourceproviders.ProviderRegistrationsLegacy),
Description: "The set of Resource Providers which should be automatically registered for the subscription.",
ValidateFunc: validation.StringInSlice([]string{
"core",
"extended",
"all",
"none",
"legacy",
resourceproviders.ProviderRegistrationsCore,
resourceproviders.ProviderRegistrationsExtended,
resourceproviders.ProviderRegistrationsAll,
resourceproviders.ProviderRegistrationsNone,
resourceproviders.ProviderRegistrationsLegacy,
}, false),
},

Expand Down Expand Up @@ -482,33 +482,22 @@ func providerConfigure(p *schema.Provider) schema.ConfigureContextFunc {
// cloud environment and authentication-related settings, use the providerConfigure function.
func buildClient(ctx context.Context, p *schema.Provider, d *schema.ResourceData, authConfig *auth.Credentials) (*clients.Client, diag.Diagnostics) {
// TODO: This hardcoded default is for v3.x, where `resource_provider_registrations` is not defined. Remove this hardcoded default in v4.0
providerRegistrations := "legacy"
providerRegistrations := resourceproviders.ProviderRegistrationsLegacy
if features.FourPointOhBeta() {
providerRegistrations = d.Get("resource_provider_registrations").(string)
}

// TODO: Remove in v5.0
if d.Get("skip_provider_registration").(bool) {
if providerRegistrations != "legacy" {
if providerRegistrations != resourceproviders.ProviderRegistrationsLegacy {
return nil, diag.Errorf("provider property `skip_provider_registration` cannot be set at the same time as `resource_provider_registrations`, please remove `skip_provider_registration` from your configuration or unset the `ARM_SKIP_PROVIDER_REGISTRATION` environment variable")
}
providerRegistrations = "none"
providerRegistrations = resourceproviders.ProviderRegistrationsNone
}

requiredResourceProviders := make(resourceproviders.ResourceProviders)
switch providerRegistrations {
case "core":
requiredResourceProviders = resourceproviders.Core()
case "extended":
requiredResourceProviders = resourceproviders.Extended()
case "all":
requiredResourceProviders = resourceproviders.All()
case "none":
// defining this explicitly even though there is nothing to do here
case "legacy":
requiredResourceProviders = resourceproviders.Legacy()
default:
return nil, diag.Errorf("unsupported value %q for provider property `resource_provider_registrations`", providerRegistrations)
requiredResourceProviders, err := resourceproviders.GetResourceProvidersSet(providerRegistrations)
if err != nil {
return nil, diag.FromErr(err)
}

if features.FourPointOhBeta() {
Expand Down
31 changes: 31 additions & 0 deletions internal/resourceproviders/required.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

package resourceproviders

import (
"fmt"
"strings"
)

// This file contains sets of resource providers which the provider should automatically register, depending on
// configuration by the user. Historically, we have ordained the same set of RPs for all users, and users could
// enable or disable automatic registration of the RPs in that set.
Expand All @@ -16,6 +21,14 @@ package resourceproviders

type ResourceProviders map[string]struct{}

const (
ProviderRegistrationsNone = "none"
ProviderRegistrationsLegacy = "legacy"
ProviderRegistrationsCore = "core"
ProviderRegistrationsExtended = "extended"
ProviderRegistrationsAll = "all"
)

func (r ResourceProviders) Add(providers ...string) {
for _, p := range providers {
r[p] = struct{}{}
Expand Down Expand Up @@ -189,3 +202,21 @@ func Legacy() ResourceProviders {
"microsoft.insights": {},
}
}

func GetResourceProvidersSet(input string) (ResourceProviders, error) {
empty := make(ResourceProviders)
switch strings.ToLower(input) {
case ProviderRegistrationsLegacy:
return Legacy(), nil
case ProviderRegistrationsCore:
return Core(), nil
case ProviderRegistrationsAll:
return All(), nil
case ProviderRegistrationsExtended:
return Extended(), nil
case ProviderRegistrationsNone:
return empty, nil
}

return empty, fmt.Errorf("unsupported value %q for provider property `resource_provider_registrations`", input)
}

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

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

Loading

0 comments on commit ecff80a

Please sign in to comment.