in Source/Actions/Microsoft.Deployment.Actions.MsCrm/CrmCreateVaultSecret.cs [91:223]
public override async Task<ActionResponse> ExecuteActionAsync(ActionRequest request)
{
string azureToken = request.DataStore.GetJson("AzureTokenKV", "access_token");
string refreshToken = request.DataStore.GetJson("AzureTokenKV", "refresh_token");
string crmToken = request.DataStore.GetJson("MsCrmToken", "access_token");
string resourceGroup = request.DataStore.GetValue("SelectedResourceGroup");
string vaultName = request.DataStore.GetValue("VaultName") ?? "bpstv-" + RandomGenerator.GetRandomLowerCaseCharacters(12) ;
string secretName = request.DataStore.GetValue("SecretName") ?? "bpst-mscrm-secret";
string connectionString = request.DataStore.GetAllValues("SqlConnectionString")[0];
string organizationId = request.DataStore.GetValue("OrganizationId");
_subscriptionId = request.DataStore.GetJson("SelectedSubscription", "SubscriptionId");
RetrieveKVToken(refreshToken, request.Info.WebsiteRootUrl, request.DataStore);
RetrieveGraphToken(refreshToken, request.Info.WebsiteRootUrl, request.DataStore);
SubscriptionCloudCredentials credentials = new TokenCloudCredentials(_subscriptionId, azureToken);
// Get user's object ID and tenant ID (in the Azure subscription where the vault is created)
string oid = null;
int propCount = 0;
foreach (var c in new JwtSecurityToken(azureToken).Claims)
{
switch (c.Type.ToLowerInvariant())
{
case "oid":
oid = c.Value;
propCount++;
break;
case "tid":
_tenantId = c.Value;
propCount++;
break;
}
if (propCount >= 2)
break;
}
// Get user's tenant ID in the CRM implicit subscription
string crmtenantId = null;
foreach (var c in new JwtSecurityToken(crmToken).Claims)
{
if (c.Type.EqualsIgnoreCase("tid"))
{
crmtenantId = c.Value;
break;
}
}
try
{
TokenCredentials credentialsKv = new TokenCredentials(azureToken);
using (KeyVaultManagementClient client = new KeyVaultManagementClient(credentialsKv))
{
client.SubscriptionId = _subscriptionId;
// Check if a vault already exists
var vaults = client.Vaults.ListByResourceGroup(resourceGroup);
foreach (var v in client.Vaults.ListByResourceGroup(resourceGroup))
{
if (v.Name.EqualsIgnoreCase(vaultName))
{
client.Vaults.Delete(resourceGroup, vaultName);
break;
}
}
// Create the vault
string vaultUrl = null;
using (ResourceManagementClient resourceClient = new ResourceManagementClient(credentials))
{
// Set properties
VaultProperties p = new VaultProperties()
{
Sku = new Sku(SkuName.Standard),
TenantId = new Guid(_tenantId),
AccessPolicies = new List<AccessPolicyEntry>()
};
// Access policy for the owner
AccessPolicyEntry apeOwner = new AccessPolicyEntry();
apeOwner.Permissions = new Permissions(new[] { "get", "create", "delete", "list", "update", "import", "backup", "restore" }, new[] { "all" }, new[] { "all" });
apeOwner.TenantId = p.TenantId;
apeOwner.ObjectId = oid;
p.AccessPolicies.Add(apeOwner);
// Access policy for the CRM exporter
AccessPolicyEntry ape = new AccessPolicyEntry();
ape.Permissions = new Permissions(null, new[] { "get" });
ape.TenantId = p.TenantId;
ape.ObjectId = GetCrmConnectorObjectID(_graphToken, _tenantId).Result;
p.AccessPolicies.Add(ape);
VaultCreateOrUpdateParameters vaultParams = new VaultCreateOrUpdateParameters()
{
Location = resourceClient.ResourceGroups.Get(resourceGroup).ResourceGroup.Location,
Properties = p
};
Vault vault = client.Vaults.CreateOrUpdate(resourceGroup, vaultName, vaultParams);
vaultUrl = vault.Properties.VaultUri;
Thread.Sleep(15000); // The vault DNS entry isn't there immediatly
}
// Create the secret
KeyVaultClient kvClient = new KeyVaultClient( new TokenCredentials(_kvToken));
SecretBundle secret = await kvClient.SetSecretAsync(vaultUrl,
secretName,
connectionString,
new Dictionary<string, string>() { { organizationId, crmtenantId } },
null /* Do I need to set a content type? */,
new SecretAttributes() { Enabled = true });
request.DataStore.AddToDataStore("KeyVault", secret.Id, DataStoreType.Private);
}
}
catch (Exception)
{
throw;
}
//Log kv name
request.Logger.LogResource(request.DataStore, vaultName,
DeployedResourceType.KeyVault, CreatedBy.BPST, DateTime.UtcNow.ToString("o"));
return new ActionResponse(ActionStatus.Success, JsonUtility.GetEmptyJObject(), true);
}