Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subscriptions: refactoring to use hashicorp/go-azure-sdk #24663

Merged
merged 12 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 14 additions & 8 deletions internal/services/authorization/role_assignment_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2020-04-01-preview/authorization" // nolint: staticcheck
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2021-01-01/subscriptions" // nolint: staticcheck
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-12-01/subscriptions"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
Expand Down Expand Up @@ -156,7 +156,7 @@ func resourceArmRoleAssignment() *pluginsdk.Resource {
func resourceArmRoleAssignmentCreate(d *pluginsdk.ResourceData, meta interface{}) error {
roleAssignmentsClient := meta.(*clients.Client).Authorization.RoleAssignmentsClient
roleDefinitionsClient := meta.(*clients.Client).Authorization.RoleDefinitionsClient
subscriptionClient := meta.(*clients.Client).Subscription.Client
subscriptionClient := meta.(*clients.Client).Subscription.SubscriptionsClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()
Expand Down Expand Up @@ -415,15 +415,21 @@ func roleAssignmentCreateStateRefreshFunc(ctx context.Context, client *authoriza
}
}

func getTenantIdBySubscriptionId(ctx context.Context, client *subscriptions.Client, subscriptionId string) (string, error) {
resp, err := client.Get(ctx, subscriptionId)
func getTenantIdBySubscriptionId(ctx context.Context, client *subscriptions.SubscriptionsClient, subscriptionId string) (string, error) {
id := commonids.NewSubscriptionID(subscriptionId)
resp, err := client.Get(ctx, id)
if err != nil {
return "", fmt.Errorf("get tenant Id by Subscription %s: %+v", subscriptionId, err)
return "", fmt.Errorf("retrieving %s: %+v", id, err)
}
if resp.TenantID == nil {
return "", fmt.Errorf("tenant Id is nil by Subscription %s: %+v", subscriptionId, resp)
tenantId := ""
if model := resp.Model; model != nil && model.TenantId != nil {
tenantId = *model.TenantId
}

if tenantId == "" {
return "", fmt.Errorf("retrieving %s: `tenantId` was nil", id)
}
return *resp.TenantID, nil
return tenantId, nil
}

func normalizeScopeValue(scope string) (result string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (br roleAssignmentBaseResource) createFunc(resourceName, scope string) sdk.
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
roleAssignmentsClient := metadata.Client.Authorization.ScopedRoleAssignmentsClient
roleDefinitionsClient := metadata.Client.Authorization.ScopedRoleDefinitionsClient
subscriptionClient := metadata.Client.Subscription.Client
subscriptionClient := metadata.Client.Subscription.SubscriptionsClient
subscriptionId := metadata.Client.Account.SubscriptionId
name := metadata.ResourceData.Get("name").(string)

Expand Down
18 changes: 6 additions & 12 deletions internal/services/subscription/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,28 @@ package client
import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2021-01-01/subscriptions" // nolint: staticcheck
resourceManager "github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-12-01/subscriptions"
subscriptionAliasPandora "github.com/hashicorp/go-azure-sdk/resource-manager/subscription/2021-10-01/subscriptions" // nolint: staticcheck
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-12-01/subscriptions"
subscriptionAlias "github.com/hashicorp/go-azure-sdk/resource-manager/subscription/2021-10-01/subscriptions"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
Client *subscriptions.Client
AliasClient *subscriptionAliasPandora.SubscriptionsClient
SubscriptionsClient *resourceManager.SubscriptionsClient
AliasClient *subscriptionAlias.SubscriptionsClient
SubscriptionsClient *subscriptions.SubscriptionsClient
}

func NewClient(o *common.ClientOptions) (*Client, error) {
client := subscriptions.NewClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&client.Client, o.ResourceManagerAuthorizer)

aliasClient := subscriptionAliasPandora.NewSubscriptionsClientWithBaseURI(o.ResourceManagerEndpoint)
aliasClient := subscriptionAlias.NewSubscriptionsClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&aliasClient.Client, o.ResourceManagerAuthorizer)

subscriptionsClient, err := resourceManager.NewSubscriptionsClientWithBaseURI(o.Environment.ResourceManager)
subscriptionsClient, err := subscriptions.NewSubscriptionsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building Subscriptions client: %+v", err)
}
o.Configure(subscriptionsClient.Client, o.Authorizers.ResourceManager)

return &Client{
AliasClient: &aliasClient,
Client: &client,
SubscriptionsClient: subscriptionsClient,
}, nil
}
39 changes: 24 additions & 15 deletions internal/services/subscription/data_source_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import (
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func dataSourceSubscription() *pluginsdk.Resource {
Expand Down Expand Up @@ -58,14 +60,14 @@ func dataSourceSubscription() *pluginsdk.Resource {
Computed: true,
},

"tags": tags.SchemaDataSource(),
"tags": commonschema.TagsDataSource(),
},
}
}

func dataSourceSubscriptionRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client)
groupClient := client.Subscription.Client
groupClient := client.Subscription.SubscriptionsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

Expand All @@ -75,25 +77,32 @@ func dataSourceSubscriptionRead(d *pluginsdk.ResourceData, meta interface{}) err
}

id := commonids.NewSubscriptionID(subscriptionId)
resp, err := groupClient.Get(ctx, subscriptionId)
resp, err := groupClient.Get(ctx, id)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}

return fmt.Errorf("retrieving %s: %+v", id, err)
}

d.SetId(id.ID())
d.Set("subscription_id", resp.SubscriptionID)
d.Set("display_name", resp.DisplayName)
d.Set("tenant_id", resp.TenantID)
d.Set("state", resp.State)
if props := resp.SubscriptionPolicies; props != nil {
d.Set("location_placement_id", props.LocationPlacementID)
d.Set("quota_id", props.QuotaID)
d.Set("spending_limit", props.SpendingLimit)

if model := resp.Model; model != nil {
d.Set("subscription_id", model.SubscriptionId)
d.Set("display_name", model.DisplayName)
d.Set("tenant_id", model.TenantId)
d.Set("state", string(pointer.From(model.State)))
if props := model.SubscriptionPolicies; props != nil {
d.Set("location_placement_id", props.LocationPlacementId)
d.Set("quota_id", props.QuotaId)
d.Set("spending_limit", string(pointer.From(props.SpendingLimit)))
}

if err := tags.FlattenAndSet(d, model.Tags); err != nil {
return err
}
}

return tags.FlattenAndSet(d, resp.Tags)
return nil
}
73 changes: 30 additions & 43 deletions internal/services/subscription/data_source_subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"strings"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
)
Expand Down Expand Up @@ -76,7 +78,7 @@ func dataSourceSubscriptions() *pluginsdk.Resource {
Computed: true,
},

"tags": tags.SchemaDataSource(),
"tags": commonschema.TagsDataSource(),
},
},
},
Expand All @@ -86,7 +88,7 @@ func dataSourceSubscriptions() *pluginsdk.Resource {

func dataSourceSubscriptionsRead(d *pluginsdk.ResourceData, meta interface{}) error {
armClient := meta.(*clients.Client)
subClient := armClient.Subscription.Client
subClient := armClient.Subscription.SubscriptionsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

Expand All @@ -99,60 +101,45 @@ func dataSourceSubscriptionsRead(d *pluginsdk.ResourceData, meta interface{}) er
return fmt.Errorf("listing subscriptions: %+v", err)
}

// iterate across each subscriptions and append them to slice
subscriptions := make([]map[string]interface{}, 0)
for results.NotDone() {
val := results.Value()

s := make(map[string]interface{})

if v := val.ID; v != nil {
s["id"] = *v
}
if v := val.SubscriptionID; v != nil {
s["subscription_id"] = *v
}
if v := val.TenantID; v != nil {
s["tenant_id"] = *v
}
if v := val.DisplayName; v != nil {
s["display_name"] = *v
}
s["state"] = string(val.State)

if policies := val.SubscriptionPolicies; policies != nil {
if v := policies.LocationPlacementID; v != nil {
s["location_placement_id"] = *v
}
if v := policies.QuotaID; v != nil {
s["quota_id"] = *v
}
s["spending_limit"] = string(policies.SpendingLimit)
}

if err = results.Next(); err != nil {
return fmt.Errorf("going to next subscriptions value: %+v", err)
}

subscriptions := make([]interface{}, 0)
for _, item := range results.Items {
// check if the display name prefix matches the given input
if displayNamePrefix != "" {
if !strings.HasPrefix(strings.ToLower(s["display_name"].(string)), displayNamePrefix) {
if item.DisplayName == nil || !strings.HasPrefix(strings.ToLower(*item.DisplayName), displayNamePrefix) {
// the display name does not match the given prefix
continue
}
}

// check if the display name matches the 'contains' comparison
if displayNameContains != "" {
if !strings.Contains(strings.ToLower(s["display_name"].(string)), displayNameContains) {
if item.DisplayName == nil || !strings.Contains(strings.ToLower(*item.DisplayName), displayNameContains) {
// the display name does not match the contains check
continue
}
}

s["tags"] = tags.Flatten(val.Tags)
quotaId := ""
locationPlacementId := ""
spendingLimit := ""
if policies := item.SubscriptionPolicies; policies != nil {
locationPlacementId = pointer.From(policies.LocationPlacementId)
quotaId = pointer.From(policies.QuotaId)
if policies.SpendingLimit != nil {
spendingLimit = string(*policies.SpendingLimit)
}
}

subscriptions = append(subscriptions, s)
subscriptions = append(subscriptions, map[string]interface{}{
"display_name": pointer.From(item.DisplayName),
"id": pointer.From(item.Id),
"location_placement_id": locationPlacementId,
"quota_id": quotaId,
"spending_limit": spendingLimit,
"state": string(pointer.From(item.State)),
"subscription_id": pointer.From(item.SubscriptionId),
"tags": tags.Flatten(item.Tags),
"tenant_id": pointer.From(item.TenantId),
})
}

d.SetId("subscriptions-" + armClient.Account.TenantId)
Expand Down
25 changes: 17 additions & 8 deletions internal/services/subscription/extended_locations_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import (
"fmt"
"time"

"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2021-01-01/subscriptions" // nolint: staticcheck
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-12-01/subscriptions"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func dataSourceExtendedLocations() *pluginsdk.Resource {
Expand All @@ -40,26 +41,30 @@ func dataSourceExtendedLocations() *pluginsdk.Resource {
}

func dataSourceExtendedLocationsRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Subscription.Client
client := meta.(*clients.Client).Subscription.SubscriptionsClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id := commonids.NewSubscriptionID(subscriptionId)
includeExtendedLocations := utils.Bool(true)
resp, err := client.ListLocations(ctx, id.SubscriptionId, includeExtendedLocations)
opts := subscriptions.DefaultListLocationsOperationOptions()
opts.IncludeExtendedLocations = pointer.To(true)
resp, err := client.ListLocations(ctx, id, opts)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s was not found", id)
}

return fmt.Errorf("retrieving %s: %+v", id, err)
}
if resp.Model == nil {
return fmt.Errorf("retrieving %s: `model` was nil", id)
}

normalizedLocation := location.Normalize(d.Get("location").(string))
d.SetId(fmt.Sprintf("%s/locations/%s", id.ID(), normalizedLocation))

extendedLocations := getExtendedLocations(resp.Value, normalizedLocation)
extendedLocations := getExtendedLocations(resp.Model.Value, normalizedLocation)
if len(extendedLocations) == 0 {
return fmt.Errorf("no extended locations were found for the location %q", normalizedLocation)
}
Expand All @@ -77,7 +82,11 @@ func getExtendedLocations(input *[]subscriptions.Location, normalizedLocation st
}

for _, item := range *input {
if item.Type != subscriptions.LocationTypeEdgeZone || item.Metadata == nil || item.Metadata.HomeLocation == nil || item.Name == nil {
if item.Type == nil || item.Metadata == nil || item.Metadata.HomeLocation == nil || item.Name == nil {
continue
}

if *item.Type != subscriptions.LocationTypeEdgeZone {
continue
}

Expand Down
18 changes: 13 additions & 5 deletions internal/services/subscription/subscription_import.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"context"
"fmt"

"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2021-01-01/subscriptions" // nolint: staticcheck
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/resources/2022-12-01/subscriptions"
subscriptionAliasPandora "github.com/hashicorp/go-azure-sdk/resource-manager/subscription/2021-10-01/subscriptions"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
Expand All @@ -16,7 +17,7 @@ import (
func importSubscriptionByAlias() pluginsdk.ImporterFunc {
return func(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) (data []*pluginsdk.ResourceData, err error) {
aliasClient := meta.(*clients.Client).Subscription.AliasClient
client := meta.(*clients.Client).Subscription.Client
client := meta.(*clients.Client).Subscription.SubscriptionsClient
aliasId, err := subscriptionAliasPandora.ParseAliasID(d.Id())
if err != nil {
return []*pluginsdk.ResourceData{}, fmt.Errorf("failed parsing Subscription Alias ID for import")
Expand All @@ -28,11 +29,18 @@ func importSubscriptionByAlias() pluginsdk.ImporterFunc {
if alias.Model == nil || alias.Model.Properties == nil || alias.Model.Properties.SubscriptionId == nil {
return []*pluginsdk.ResourceData{}, fmt.Errorf("failed reading Subscription Alias Properties, empty response or missing Subscription ID")
}
subscription, err := client.Get(ctx, *alias.Model.Properties.SubscriptionId)
subscriptionResourceId := commonids.NewSubscriptionID(*alias.Model.Properties.SubscriptionId)
subscription, err := client.Get(ctx, subscriptionResourceId)
if err != nil {
return []*pluginsdk.ResourceData{}, fmt.Errorf("failed parsing Subscription details for import: %+v", err)
return []*pluginsdk.ResourceData{}, fmt.Errorf("retrieving %s: %+v", subscriptionResourceId, err)
}
if subscription.State != subscriptions.StateEnabled {
if subscription.Model == nil {
return []*pluginsdk.ResourceData{}, fmt.Errorf("retrieving %s: `model` was nil", subscriptionResourceId)
}
if subscription.Model.SubscriptionId == nil {
return []*pluginsdk.ResourceData{}, fmt.Errorf("retrieving %s: `model.SubscriptionId` was nil", subscriptionResourceId)
}
if *subscription.Model.State != subscriptions.SubscriptionStateEnabled {
return []*pluginsdk.ResourceData{}, fmt.Errorf("cannot import a cancelled Subscription by Alias ID, please enable the subscription prior to import")
}
return []*pluginsdk.ResourceData{d}, nil
Expand Down