tools/code/publisher/WorkspaceNamedValue.cs (205 lines of code) (raw):
using Azure.Core.Pipeline;
using common;
using LanguageExt;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace publisher;
public delegate ValueTask PutWorkspaceNamedValues(CancellationToken cancellationToken);
public delegate Option<(NamedValueName Name, WorkspaceName WorkspaceName)> TryParseWorkspaceNamedValueName(FileInfo file);
public delegate bool IsWorkspaceNamedValueNameInSourceControl(NamedValueName name, WorkspaceName workspaceName);
public delegate ValueTask PutWorkspaceNamedValue(NamedValueName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask<Option<WorkspaceNamedValueDto>> FindWorkspaceNamedValueDto(NamedValueName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask PutWorkspaceNamedValueInApim(NamedValueName name, WorkspaceNamedValueDto dto, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspaceNamedValues(CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspaceNamedValue(NamedValueName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspaceNamedValueFromApim(NamedValueName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
internal static class WorkspaceNamedValueModule
{
public static void ConfigurePutWorkspaceNamedValues(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryWorkspaceParseNamedValueName(builder);
ConfigureIsWorkspaceNamedValueNameInSourceControl(builder);
ConfigurePutWorkspaceNamedValue(builder);
builder.Services.TryAddSingleton(GetPutWorkspaceNamedValues);
}
private static PutWorkspaceNamedValues GetPutWorkspaceNamedValues(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseWorkspaceNamedValueName>();
var isNameInSourceControl = provider.GetRequiredService<IsWorkspaceNamedValueNameInSourceControl>();
var put = provider.GetRequiredService<PutWorkspaceNamedValue>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(PutWorkspaceNamedValues));
logger.LogInformation("Putting workspace named values...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(tag => isNameInSourceControl(tag.Name, tag.WorkspaceName))
.Distinct()
.IterParallel(put.Invoke, cancellationToken);
};
}
private static void ConfigureTryWorkspaceParseNamedValueName(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetTryParseWorkspaceNamedValueName);
}
private static TryParseWorkspaceNamedValueName GetTryParseWorkspaceNamedValueName(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return file => from informationFile in WorkspaceNamedValueInformationFile.TryParse(file, serviceDirectory)
select (informationFile.Parent.Name, informationFile.Parent.Parent.Parent.Name);
}
private static void ConfigureIsWorkspaceNamedValueNameInSourceControl(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetArtifactFiles(builder);
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetIsNamedValueNameInSourceControl);
}
private static IsWorkspaceNamedValueNameInSourceControl GetIsNamedValueNameInSourceControl(IServiceProvider provider)
{
var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>();
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return doesInformationFileExist;
bool doesInformationFileExist(NamedValueName name, WorkspaceName workspaceName)
{
var artifactFiles = getArtifactFiles();
var tagFile = WorkspaceNamedValueInformationFile.From(name, workspaceName, serviceDirectory);
return artifactFiles.Contains(tagFile.ToFileInfo());
}
}
private static void ConfigurePutWorkspaceNamedValue(IHostApplicationBuilder builder)
{
ConfigureFindWorkspaceNamedValueDto(builder);
ConfigurePutWorkspaceNamedValueInApim(builder);
builder.Services.TryAddSingleton(GetPutWorkspaceNamedValue);
}
private static PutWorkspaceNamedValue GetPutWorkspaceNamedValue(IServiceProvider provider)
{
var findDto = provider.GetRequiredService<FindWorkspaceNamedValueDto>();
var putInApim = provider.GetRequiredService<PutWorkspaceNamedValueInApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, workspaceName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(PutWorkspaceNamedValue))
?.AddTag("workspace_named_value.name", name)
?.AddTag("workspace.name", workspaceName);
var dtoOption = await findDto(name, workspaceName, cancellationToken);
await dtoOption.IterTask(async dto => await putInApim(name, dto, workspaceName, cancellationToken));
};
}
private static void ConfigureFindWorkspaceNamedValueDto(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
CommonModule.ConfigureTryGetFileContents(builder);
builder.Services.TryAddSingleton(GetFindWorkspaceNamedValueDto);
}
private static FindWorkspaceNamedValueDto GetFindWorkspaceNamedValueDto(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>();
return async (name, workspaceName, cancellationToken) =>
{
var informationFile = WorkspaceNamedValueInformationFile.From(name, workspaceName, serviceDirectory);
var contentsOption = await tryGetFileContents(informationFile.ToFileInfo(), cancellationToken);
return from contents in contentsOption
select contents.ToObjectFromJson<WorkspaceNamedValueDto>();
};
}
private static void ConfigurePutWorkspaceNamedValueInApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetPutWorkspaceNamedValueInApim);
}
private static PutWorkspaceNamedValueInApim GetPutWorkspaceNamedValueInApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, dto, workspaceName, cancellationToken) =>
{
// Don't put secret named values without a value or keyvault identifier
if (dto.Properties.Secret is true && dto.Properties.Value is null && dto.Properties.KeyVault?.SecretIdentifier is null)
{
logger.LogWarning("Named value {NamedValueName} in workspace {WorkspaceName} is secret, but no value or keyvault identifier was specified. Skipping it...", name, workspaceName);
return;
}
logger.LogInformation("Adding named value {NamedValueName} to workspace {WorkspaceName}...", name, workspaceName);
await WorkspaceNamedValueUri.From(name, workspaceName, serviceUri)
.PutDto(dto, pipeline, cancellationToken);
};
}
public static void ConfigureDeleteWorkspaceNamedValues(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryWorkspaceParseNamedValueName(builder);
ConfigureIsWorkspaceNamedValueNameInSourceControl(builder);
ConfigureDeleteWorkspaceNamedValue(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspaceNamedValues);
}
private static DeleteWorkspaceNamedValues GetDeleteWorkspaceNamedValues(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseWorkspaceNamedValueName>();
var isNameInSourceControl = provider.GetRequiredService<IsWorkspaceNamedValueNameInSourceControl>();
var delete = provider.GetRequiredService<DeleteWorkspaceNamedValue>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(DeleteWorkspaceNamedValues));
logger.LogInformation("Deleting workspace named values...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(tag => isNameInSourceControl(tag.Name, tag.WorkspaceName) is false)
.Distinct()
.IterParallel(delete.Invoke, cancellationToken);
};
}
private static void ConfigureDeleteWorkspaceNamedValue(IHostApplicationBuilder builder)
{
ConfigureDeleteWorkspaceNamedValueFromApim(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspaceNamedValue);
}
private static DeleteWorkspaceNamedValue GetDeleteWorkspaceNamedValue(IServiceProvider provider)
{
var deleteFromApim = provider.GetRequiredService<DeleteWorkspaceNamedValueFromApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, workspaceName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(DeleteWorkspaceNamedValue))
?.AddTag("workspace_named_value.name", name)
?.AddTag("workspace.name", workspaceName);
await deleteFromApim(name, workspaceName, cancellationToken);
};
}
private static void ConfigureDeleteWorkspaceNamedValueFromApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspaceNamedValueFromApim);
}
private static DeleteWorkspaceNamedValueFromApim GetDeleteWorkspaceNamedValueFromApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, workspaceName, cancellationToken) =>
{
logger.LogInformation("Removing named value {NamedValueName} from workspace {WorkspaceName}...", name, workspaceName);
await WorkspaceNamedValueUri.From(name, workspaceName, serviceUri)
.Delete(pipeline, cancellationToken);
};
}
}