Example #1
0
    private static async Task <StorageAccountItem> FindStorageAccountAsync(
        ManagedStorageRestClient storageClient,
        string storageAccountName)
    {
        for (StorageListResult result = await storageClient.GetStorageAccountsAsync(cancellationToken: s_cancellationTokenSource.Token); ;
             result = await storageClient.GetStorageAccountsNextPageAsync(result.NextLink, cancellationToken: s_cancellationTokenSource.Token))
        {
            foreach (StorageAccountItem storageAccount in result.Value)
            {
                // The storage account name is the segment of the ResourceId.
                int    pos  = storageAccount.ResourceId.AsSpan().TrimEnd('/').LastIndexOf('/');
                string name = storageAccount.ResourceId.Substring(pos + 1);

                if (string.Equals(storageAccountName, name, StringComparison.InvariantCultureIgnoreCase))
                {
                    return(storageAccount);
                }
            }

            if (result.NextLink is null)
            {
                // No more results.
                return(null);
            }
        }
    }
Example #2
0
    private static async Task <int> RunAsync(
        Uri vaultUri,
        string storageAccountName,
        int days,
        bool readOnly,
        IConsole console)
    {
        // Allow only credentials appropriate for this interactive tool sample.
        DefaultAzureCredential credential = new DefaultAzureCredential(
            new DefaultAzureCredentialOptions
        {
            ExcludeEnvironmentCredential     = true,
            ExcludeManagedIdentityCredential = true,
        });

        // Use the same options for both clients, which allow logging of some other non-PII headers.
        SecretClientOptions options = new SecretClientOptions();

        // Create the Key Vault-managed Storage client to find the specified managed storage account.
        ManagedStorageRestClient storageClient = ManagedStorageRestClient.Create(vaultUri, credential, options);

        // Find the specified manage storage account.
        StorageAccountItem storageAccount = await FindStorageAccountAsync(storageClient, storageAccountName);

        if (storageAccount is null)
        {
            console.Error.WriteLine($"Error: '{storageAccountName}' is not currently managed by {vaultUri}");
            return(1);
        }

        // Build our SAS template, get an existing SAS definition, or create a new one.
        string sasTemplate       = BuildSasDefinitionTemplate(readOnly);
        string sasDefinitionName = await GetOrCreateSasDefinitionAsync(storageClient, storageAccountName, sasTemplate, days, readOnly);

        // Now we can create a SecretClient and generate a new SAS token from the storage account and SAS definition names.
        SecretClient   secretClient = new SecretClient(vaultUri, credential, options);
        KeyVaultSecret sasToken     = await secretClient.GetSecretAsync($"{storageAccountName}-{sasDefinitionName}", cancellationToken : s_cancellationTokenSource.Token);

        console.Out.WriteLine(sasToken.Value);
        return(0);
    }
Example #3
0
    private static async Task <string> GetOrCreateSasDefinitionAsync(
        ManagedStorageRestClient storageClient,
        string storageAccountName,
        string sasTemplate,
        int days,
        bool readOnly)
    {
        const string Tag = "ShareLinkSample";

        // Format the duration using ISO 8601.
        string duration = days > 0 ? XmlConvert.ToString(TimeSpan.FromDays(days)) : null;

        // Try to find an existing definition based on the template and duration, since the formatted name may have changed.
        for (SasDefinitionListResult result = await storageClient.GetSasDefinitionsAsync(storageAccountName, cancellationToken: s_cancellationTokenSource.Token); ;
             result = await storageClient.GetSasDefinitionsNextPageAsync(result.NextLink, storageAccountName, cancellationToken: s_cancellationTokenSource.Token))
        {
            foreach (SasDefinitionItem sasDefinitionInfo in result.Value.Where(d => d.Tags.ContainsKey(Tag)))
            {
                // The SAS definition name is the segment of the Id.
                int    pos  = sasDefinitionInfo.Id.AsSpan().TrimEnd('/').LastIndexOf('/');
                string name = sasDefinitionInfo.Id.Substring(pos + 1);

                SasDefinitionBundle foundSasDefinition = await storageClient.GetSasDefinitionAsync(storageAccountName, name, cancellationToken : s_cancellationTokenSource.Token);

                if (string.Equals(sasTemplate, foundSasDefinition.TemplateUri, StringComparison.OrdinalIgnoreCase) &&
                    string.Equals(duration, foundSasDefinition.ValidityPeriod, StringComparison.OrdinalIgnoreCase))
                {
                    return(name);
                }
            }

            if (result.NextLink is null)
            {
                // No more results.
                break;
            }
        }

        // Create a new SAS definition since we didn't find an existing definition.
        string sasDefinitionName = BuildSasDefinitionName(Tag, readOnly, duration);
        SasDefinitionAttributes sasDefinitionAttributes = new SasDefinitionAttributes
        {
            Enabled = true,
        };

        Dictionary <string, string> tags = new Dictionary <string, string>
        {
            [Tag] = "1",
        };

        SasDefinitionBundle createdSasDefinition = await storageClient.SetSasDefinitionAsync(
            storageAccountName,
            sasDefinitionName,
            sasTemplate,
            SasTokenType.Account,
            duration,
            sasDefinitionAttributes,
            tags,
            s_cancellationTokenSource.Token);

        return(sasDefinitionName);
    }