diff --git a/azurerm/config.go b/azurerm/config.go index 1a4f539fd14a..afda37223e9d 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -98,6 +98,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/servicebus" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/servicefabric" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/signalr" + intStor "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/storage" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/trafficmanager" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" "github.com/terraform-providers/terraform-provider-azurerm/version" @@ -149,6 +150,7 @@ type ArmClient struct { servicebus *servicebus.Client serviceFabric *servicefabric.Client signalr *signalr.Client + storage *intStor.Client trafficManager *trafficmanager.Client // TODO: refactor @@ -1092,6 +1094,8 @@ func (c *ArmClient) registerStorageClients(endpoint, subscriptionId string, auth usageClient := storage.NewUsagesClientWithBaseURI(endpoint, subscriptionId) c.configureClient(&usageClient.Client, auth) c.storageUsageClient = usageClient + + c.storage = intStor.BuildClient(accountsClient) } func (c *ArmClient) registerStreamAnalyticsClients(endpoint, subscriptionId string, auth autorest.Authorizer) { diff --git a/azurerm/internal/services/storage/client.go b/azurerm/internal/services/storage/client.go new file mode 100644 index 000000000000..a34c42b78954 --- /dev/null +++ b/azurerm/internal/services/storage/client.go @@ -0,0 +1,84 @@ +package storage + +import ( + "context" + "fmt" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/authorizers" + "github.com/tombuildsstuff/giovanni/storage/2018-11-09/file/directories" +) + +type Client struct { + // this is currently unexported since we only use it to look up the account key + // we could export/use this in the future - but there's no point it being public + // until that time + accountsClient storage.AccountsClient +} + +// NOTE: this temporarily diverges from the other clients until we move this client in here +// once we have this, can take an Options like everything else +func BuildClient(accountsClient storage.AccountsClient) *Client { + return &Client{ + accountsClient: accountsClient, + } +} + +func (client Client) FindResourceGroup(ctx context.Context, accountName string) (*string, error) { + accounts, err := client.accountsClient.List(ctx) + if err != nil { + return nil, fmt.Errorf("Error listing Storage Accounts (to find Resource Group for %q): %s", accountName, err) + } + + if accounts.Value == nil { + return nil, nil + } + + var resourceGroup *string + for _, account := range *accounts.Value { + if account.Name == nil || account.ID == nil { + continue + } + + if strings.EqualFold(accountName, *account.Name) { + id, err := azure.ParseAzureResourceID(*account.ID) + if err != nil { + return nil, fmt.Errorf("Error parsing ID for Storage Account %q: %s", accountName, err) + } + + resourceGroup = &id.ResourceGroup + break + } + } + + return resourceGroup, nil +} + +func (client Client) FileShareClient(ctx context.Context, resourceGroup, accountName string) (*directories.Client, error) { + accountKey, err := client.findAccountKey(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error retrieving Account Key: %s", err) + } + + storageAuth := authorizers.NewSharedKeyLiteAuthorizer(accountName, *accountKey) + directoriesClient := directories.New() + directoriesClient.Client.Authorizer = storageAuth + return &directoriesClient, nil +} + +func (client Client) findAccountKey(ctx context.Context, resourceGroup, accountName string) (*string, error) { + props, err := client.accountsClient.ListKeys(ctx, resourceGroup, accountName) + if err != nil { + return nil, fmt.Errorf("Error Listing Keys for Storage Account %q (Resource Group %q): %+v", accountName, resourceGroup, err) + } + + if props.Keys == nil || len(*props.Keys) == 0 { + return nil, fmt.Errorf("Keys were nil for Storage Account %q (Resource Group %q): %+v", accountName, resourceGroup, err) + } + + keys := *props.Keys + firstKey := keys[0].Value + return firstKey, nil +} diff --git a/azurerm/internal/services/storage/metadata.go b/azurerm/internal/services/storage/metadata.go new file mode 100644 index 000000000000..1c7357e9b3ce --- /dev/null +++ b/azurerm/internal/services/storage/metadata.go @@ -0,0 +1,30 @@ +package storage + +import "github.com/hashicorp/terraform/helper/schema" + +func MetaDataSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + } +} + +func ExpandMetaData(input map[string]interface{}) map[string]string { + output := make(map[string]string, 0) + + for k, v := range input { + output[k] = v.(string) + } + + return output +} + +func FlattenMetaData(input map[string]string) map[string]interface{} { + output := make(map[string]interface{}, 0) + + for k, v := range input { + output[k] = v + } + + return output +}