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

appconfiguration: using the ListBySubscription endpoint rather than the Resources API #24023

Merged
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/Azure/go-autorest/autorest"
"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/appconfiguration/2023-03-01/configurationstores"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
Expand Down Expand Up @@ -333,8 +334,8 @@ func (k FeatureResource) Read() sdk.ResourceFunc {
return fmt.Errorf("while parsing resource ID: %+v", err)
}

resourceClient := metadata.Client.Resource
configurationStoreIdRaw, err := metadata.Client.AppConfiguration.ConfigurationStoreIDFromEndpoint(ctx, resourceClient, nestedItemId.ConfigurationStoreEndpoint)
subscriptionId := commonids.NewSubscriptionID(metadata.Client.Account.SubscriptionId)
configurationStoreIdRaw, err := metadata.Client.AppConfiguration.ConfigurationStoreIDFromEndpoint(ctx, subscriptionId, nestedItemId.ConfigurationStoreEndpoint)
if err != nil {
return fmt.Errorf("while retrieving the Resource ID of Configuration Store at Endpoint: %q: %s", nestedItemId.ConfigurationStoreEndpoint, err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/Azure/go-autorest/autorest"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/appconfiguration/2023-03-01/configurationstores"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
Expand Down Expand Up @@ -241,8 +242,8 @@ func (k KeyResource) Read() sdk.ResourceFunc {
return fmt.Errorf("while parsing resource ID: %+v", err)
}

resourceClient := metadata.Client.Resource
configurationStoreIdRaw, err := metadata.Client.AppConfiguration.ConfigurationStoreIDFromEndpoint(ctx, resourceClient, nestedItemId.ConfigurationStoreEndpoint)
subscriptionId := commonids.NewSubscriptionID(metadata.Client.Account.SubscriptionId)
configurationStoreIdRaw, err := metadata.Client.AppConfiguration.ConfigurationStoreIDFromEndpoint(ctx, subscriptionId, nestedItemId.ConfigurationStoreEndpoint)
if err != nil {
return fmt.Errorf("while retrieving the Resource ID of Configuration Store at Endpoint: %q: %s", nestedItemId.ConfigurationStoreEndpoint, err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/services/appconfiguration/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Client struct {
configureClientFunc func(c *autorest.Client, authorizer autorest.Authorizer)
}

func (c Client) DataPlaneClientWithEndpoint(configurationStoreEndpoint string) (*appconfiguration.BaseClient, error) {
func (c *Client) DataPlaneClientWithEndpoint(configurationStoreEndpoint string) (*appconfiguration.BaseClient, error) {
api := environments.NewApiEndpoint("AppConfiguration", configurationStoreEndpoint, nil)
appConfigAuth, err := c.authorizerFunc(api)
if err != nil {
Expand All @@ -40,7 +40,7 @@ func (c Client) DataPlaneClientWithEndpoint(configurationStoreEndpoint string) (
return &client, nil
}

func (c Client) LinkWorkaroundDataPlaneClientWithEndpoint(configurationStoreEndpoint string) (*azuresdkhacks.DataPlaneClient, error) {
func (c *Client) LinkWorkaroundDataPlaneClientWithEndpoint(configurationStoreEndpoint string) (*azuresdkhacks.DataPlaneClient, error) {
api := environments.NewApiEndpoint("AppConfiguration", configurationStoreEndpoint, nil)
appConfigAuth, err := c.authorizerFunc(api)
if err != nil {
Expand Down
81 changes: 34 additions & 47 deletions internal/services/appconfiguration/client/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import (
"sync"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/appconfiguration/2023-03-01/configurationstores"
resourcesClient "github.com/hashicorp/terraform-provider-azurerm/internal/services/resource/client"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

var (
ConfigurationStoreCache = map[string]ConfigurationStoreDetails{}
configurationStoreCache = map[string]ConfigurationStoreDetails{}
keysmith = &sync.RWMutex{}
lock = map[string]*sync.RWMutex{}
)
Expand All @@ -27,17 +26,17 @@ type ConfigurationStoreDetails struct {
dataPlaneEndpoint string
}

func (c Client) AddToCache(configurationStoreId configurationstores.ConfigurationStoreId, dataPlaneEndpoint string) {
func (c *Client) AddToCache(configurationStoreId configurationstores.ConfigurationStoreId, dataPlaneEndpoint string) {
cacheKey := c.cacheKeyForConfigurationStore(configurationStoreId.ConfigurationStoreName)
keysmith.Lock()
ConfigurationStoreCache[cacheKey] = ConfigurationStoreDetails{
configurationStoreCache[cacheKey] = ConfigurationStoreDetails{
configurationStoreId: configurationStoreId.ID(),
dataPlaneEndpoint: dataPlaneEndpoint,
}
keysmith.Unlock()
}

func (c Client) ConfigurationStoreIDFromEndpoint(ctx context.Context, resourcesClient *resourcesClient.Client, configurationStoreEndpoint string) (*string, error) {
func (c *Client) ConfigurationStoreIDFromEndpoint(ctx context.Context, subscriptionId commonids.SubscriptionId, configurationStoreEndpoint string) (*string, error) {
configurationStoreName, err := c.parseNameFromEndpoint(configurationStoreEndpoint)
if err != nil {
return nil, err
Expand All @@ -52,53 +51,41 @@ func (c Client) ConfigurationStoreIDFromEndpoint(ctx context.Context, resourcesC
lock[cacheKey].Lock()
defer lock[cacheKey].Unlock()

if v, ok := ConfigurationStoreCache[cacheKey]; ok {
// first check the cache
if v, ok := configurationStoreCache[cacheKey]; ok {
return &v.configurationStoreId, nil
}

filter := fmt.Sprintf("resourceType eq 'Microsoft.AppConfiguration/configurationStores' and name eq '%s'", *configurationStoreName)
result, err := resourcesClient.ResourcesClient.List(ctx, filter, "", utils.Int32(5))
// If it's not present, populate the entire cache
configurationStores, err := c.ConfigurationStoresClient.ListComplete(ctx, subscriptionId)
if err != nil {
return nil, fmt.Errorf("listing resources matching %q: %+v", filter, err)
}

for result.NotDone() {
for _, v := range result.Values() {
if v.ID == nil {
continue
}

id, err := configurationstores.ParseConfigurationStoreIDInsensitively(*v.ID)
if err != nil {
return nil, fmt.Errorf("parsing %q: %+v", *v.ID, err)
}
if !strings.EqualFold(id.ConfigurationStoreName, *configurationStoreName) {
continue
}

resp, err := c.ConfigurationStoresClient.Get(ctx, *id)
if err != nil {
return nil, fmt.Errorf("retrieving %s: %+v", *id, err)
}
if resp.Model == nil || resp.Model.Properties == nil || resp.Model.Properties.Endpoint == nil {
return nil, fmt.Errorf("retrieving %s: `model.properties.Endpoint` was nil", *id)
}

c.AddToCache(*id, *resp.Model.Properties.Endpoint)

return utils.String(id.ID()), nil
return nil, fmt.Errorf("retrieving the list of Configuration Stores in %s: %+v", subscriptionId, err)
}
for _, item := range configurationStores.Items {
if item.Id == nil || item.Properties == nil || item.Properties.Endpoint == nil {
continue
}

if err := result.NextWithContext(ctx); err != nil {
return nil, fmt.Errorf("iterating over results: %+v", err)
itemId := *item.Id
endpointUri := *item.Properties.Endpoint
configurationStoreId, err := configurationstores.ParseConfigurationStoreIDInsensitively(itemId)
if err != nil {
return nil, fmt.Errorf("parsing %q: %+v", itemId, err)
}

c.AddToCache(*configurationStoreId, endpointUri)
}

// finally try and pull this from the cache
if v, ok := configurationStoreCache[cacheKey]; ok {
return &v.configurationStoreId, nil
}

// we haven't found it, but Data Sources and Resources need to handle this error separately
return nil, nil
}

func (c Client) EndpointForConfigurationStore(ctx context.Context, configurationStoreId configurationstores.ConfigurationStoreId) (*string, error) {
func (c *Client) EndpointForConfigurationStore(ctx context.Context, configurationStoreId configurationstores.ConfigurationStoreId) (*string, error) {
cacheKey := c.cacheKeyForConfigurationStore(configurationStoreId.ConfigurationStoreName)
keysmith.Lock()
if lock[cacheKey] == nil {
Expand All @@ -108,7 +95,7 @@ func (c Client) EndpointForConfigurationStore(ctx context.Context, configuration
lock[cacheKey].Lock()
defer lock[cacheKey].Unlock()

if v, ok := ConfigurationStoreCache[cacheKey]; ok {
if v, ok := configurationStoreCache[cacheKey]; ok {
return &v.dataPlaneEndpoint, nil
}

Expand All @@ -126,7 +113,7 @@ func (c Client) EndpointForConfigurationStore(ctx context.Context, configuration
return resp.Model.Properties.Endpoint, nil
}

func (c Client) Exists(ctx context.Context, configurationStoreId configurationstores.ConfigurationStoreId) (bool, error) {
func (c *Client) Exists(ctx context.Context, configurationStoreId configurationstores.ConfigurationStoreId) (bool, error) {
cacheKey := c.cacheKeyForConfigurationStore(configurationStoreId.ConfigurationStoreName)
keysmith.Lock()
if lock[cacheKey] == nil {
Expand All @@ -136,7 +123,7 @@ func (c Client) Exists(ctx context.Context, configurationStoreId configurationst
lock[cacheKey].Lock()
defer lock[cacheKey].Unlock()

if _, ok := ConfigurationStoreCache[cacheKey]; ok {
if _, ok := configurationStoreCache[cacheKey]; ok {
return true, nil
}

Expand All @@ -157,23 +144,23 @@ func (c Client) Exists(ctx context.Context, configurationStoreId configurationst
return true, nil
}

func (c Client) RemoveFromCache(configurationStoreId configurationstores.ConfigurationStoreId) {
func (c *Client) RemoveFromCache(configurationStoreId configurationstores.ConfigurationStoreId) {
cacheKey := c.cacheKeyForConfigurationStore(configurationStoreId.ConfigurationStoreName)
keysmith.Lock()
if lock[cacheKey] == nil {
lock[cacheKey] = &sync.RWMutex{}
}
keysmith.Unlock()
lock[cacheKey].Lock()
delete(ConfigurationStoreCache, cacheKey)
delete(configurationStoreCache, cacheKey)
lock[cacheKey].Unlock()
}

func (c Client) cacheKeyForConfigurationStore(name string) string {
func (c *Client) cacheKeyForConfigurationStore(name string) string {
return strings.ToLower(name)
}

func (c Client) parseNameFromEndpoint(input string) (*string, error) {
func (c *Client) parseNameFromEndpoint(input string) (*string, error) {
uri, err := url.ParseRequestURI(input)
if err != nil {
return nil, err
Expand Down
Loading