Skip to content
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
18 changes: 11 additions & 7 deletions src/aggregator-cli/CommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,26 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace aggregator.cli
{
abstract class CommandBase
{
ILogger logger = null;
ILogger logger;

// Omitting long name, defaults to name of property, ie "--verbose"
[Option('v', "verbose", Default = false, HelpText = "Prints all messages to standard output.")]
public bool Verbose { get; set; }

protected ContextBuilder Context => new ContextBuilder(logger);

internal abstract Task<int> RunAsync();
internal abstract Task<int> RunAsync(CancellationToken cancellationToken);

internal int Run()
internal int Run(CancellationToken cancellationToken)
{
this.logger = new ConsoleLogger(Verbose);
logger = new ConsoleLogger(Verbose);
try
{
var title = GetCustomAttribute<AssemblyTitleAttribute>();
Expand All @@ -35,16 +36,19 @@ internal int Run()
// Hello World
logger.WriteInfo($"{title.Title} v{infoVersion.InformationalVersion} (build: {fileVersion.Version} {config.Configuration}) (c) {copyright.Copyright}");

var t = this.RunAsync();
t.Wait();
var t = RunAsync(cancellationToken);
t.Wait(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
int rc = t.Result;
if (rc != 0)
{
logger.WriteError("Failed!");
} else
}
else
{
logger.WriteSuccess("Succeeded");
}

return rc;
}
catch (Exception ex)
Expand Down
11 changes: 8 additions & 3 deletions src/aggregator-cli/ContextBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace aggregator.cli
Expand Down Expand Up @@ -34,12 +35,14 @@ internal ContextBuilder WithAzureLogon()
azureLogon = true;
return this;
}

internal ContextBuilder WithDevOpsLogon()
{
devopsLogon = true;
return this;
}
internal async Task<CommandContext> Build()

internal async Task<CommandContext> BuildAsync(CancellationToken cancellationToken)
{
IAzure azure = null;
VssConnection devops = null;
Expand All @@ -53,7 +56,8 @@ internal async Task<CommandContext> Build()
string msg = TranslateResult(reason);
throw new ApplicationException(string.Format(msg, "Azure","logon.azure"));
}
azure = await connection.LogonAsync();

azure = connection.Logon();
logger.WriteInfo($"Connected to subscription {azure.SubscriptionId}");
}

Expand All @@ -66,7 +70,8 @@ internal async Task<CommandContext> Build()
string msg = TranslateResult(reason);
throw new ApplicationException(string.Format(msg, "Azure DevOps", "logon.ado"));
}
devops = await connection.LogonAsync();

devops = await connection.LogonAsync(cancellationToken);
logger.WriteInfo($"Connected to {devops.Uri.Host}");
}

Expand Down
48 changes: 24 additions & 24 deletions src/aggregator-cli/Instances/AggregatorInstances.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace aggregator.cli
Expand All @@ -23,10 +23,10 @@ public AggregatorInstances(IAzure azure, ILogger logger)
this.logger = logger;
}

public async Task<IEnumerable<ILogDataObject>> ListAllAsync()
public async Task<IEnumerable<ILogDataObject>> ListAllAsync(CancellationToken cancellationToken)
{
var runtime = new FunctionRuntimePackage(logger);
var rgs = await azure.ResourceGroups.ListAsync();
var rgs = await azure.ResourceGroups.ListAsync(cancellationToken: cancellationToken);
var filter = rgs
.Where(rg => rg.Name.StartsWith(InstanceName.ResourceGroupInstancePrefix));
var result = new List<InstanceOutputData>();
Expand All @@ -36,16 +36,16 @@ public async Task<IEnumerable<ILogDataObject>> ListAllAsync()
result.Add(new InstanceOutputData(
name.PlainName,
rg.RegionName,
await runtime.GetDeployedRuntimeVersion(name, azure))
await runtime.GetDeployedRuntimeVersion(name, azure, cancellationToken))
);
}
return result;
}

public async Task<IEnumerable<ILogDataObject>> ListByLocationAsync(string location)
public async Task<IEnumerable<ILogDataObject>> ListByLocationAsync(string location, CancellationToken cancellationToken)
{
var runtime = new FunctionRuntimePackage(logger);
var rgs = await azure.ResourceGroups.ListAsync();
var rgs = await azure.ResourceGroups.ListAsync(cancellationToken: cancellationToken);
var filter = rgs.Where(rg =>
rg.Name.StartsWith(InstanceName.ResourceGroupInstancePrefix)
&& rg.RegionName.CompareTo(location) == 0);
Expand All @@ -56,36 +56,36 @@ public async Task<IEnumerable<ILogDataObject>> ListByLocationAsync(string locati
result.Add(new InstanceOutputData(
name.PlainName,
rg.RegionName,
await runtime.GetDeployedRuntimeVersion(name, azure))
await runtime.GetDeployedRuntimeVersion(name, azure, cancellationToken))
);
}
return result;
}

internal async Task<IEnumerable<ILogDataObject>> ListInResourceGroupAsync(string resourceGroup)
internal async Task<IEnumerable<ILogDataObject>> ListInResourceGroupAsync(string resourceGroup, CancellationToken cancellationToken)
{
var runtime = new FunctionRuntimePackage(logger);
var apps = await azure.AppServices.FunctionApps.ListByResourceGroupAsync(resourceGroup);
var apps = await azure.AppServices.FunctionApps.ListByResourceGroupAsync(resourceGroup, cancellationToken: cancellationToken);

var result = new List<InstanceOutputData>();
foreach (var app in apps)
{
cancellationToken.ThrowIfCancellationRequested();
var name = InstanceName.FromFunctionAppName(app.Name, resourceGroup);
result.Add(new InstanceOutputData(
name.PlainName,
app.Region.Name,
await runtime.GetDeployedRuntimeVersion(name, azure))
await runtime.GetDeployedRuntimeVersion(name, azure, cancellationToken))
);
}
return result;
}


internal async Task<bool> Add(InstanceName instance, string location, string requiredVersion)
internal async Task<bool> AddAsync(InstanceName instance, string location, string requiredVersion, CancellationToken cancellationToken)
{
string rgName = instance.ResourceGroupName;
logger.WriteVerbose($"Checking if Resource Group {rgName} already exists");
if (!await azure.ResourceGroups.ContainAsync(rgName))
if (!await azure.ResourceGroups.ContainAsync(rgName, cancellationToken))
{
if (instance.IsCustom)
{
Expand Down Expand Up @@ -131,7 +131,7 @@ await azure.ResourceGroups
.WithTemplate(armTemplateString)
.WithParameters(templateParams)
.WithMode(DeploymentMode.Incremental)
.CreateAsync();
.CreateAsync(cancellationToken);

// poll
const int PollIntervalInSeconds = 3;
Expand All @@ -143,20 +143,20 @@ await azure.ResourceGroups
SdkContext.DelayProvider.Delay(PollIntervalInSeconds * 1000);
totalDelay += PollIntervalInSeconds;
logger.WriteVerbose($"Deployment running ({totalDelay}s)");
await deployment.RefreshAsync();
await deployment.RefreshAsync(cancellationToken);
}
logger.WriteInfo($"Deployment {deployment.ProvisioningState}");

// check runtime package
var package = new FunctionRuntimePackage(logger);
bool ok = await package.UpdateVersion(requiredVersion, instance, azure);
bool ok = await package.UpdateVersionAsync(requiredVersion, instance, azure, cancellationToken);
if (ok)
{
var devopsLogonData = DevOpsLogon.Load().connection;
if (devopsLogonData.Mode == DevOpsTokenType.PAT)
{
logger.WriteVerbose($"Saving Azure DevOps token");
ok = await ChangeAppSettings(instance, devopsLogonData, SaveMode.Default);
ok = await ChangeAppSettingsAsync(instance, devopsLogonData, SaveMode.Default, cancellationToken);
if (ok)
{
logger.WriteInfo($"Azure DevOps token saved");
Expand All @@ -175,14 +175,14 @@ await azure.ResourceGroups
return ok;
}

internal async Task<bool> ChangeAppSettings(InstanceName instance, DevOpsLogon devopsLogonData, SaveMode saveMode)
internal async Task<bool> ChangeAppSettingsAsync(InstanceName instance, DevOpsLogon devopsLogonData, SaveMode saveMode, CancellationToken cancellationToken)
{
var webFunctionApp = await azure
.AppServices
.WebApps
.GetByResourceGroupAsync(
instance.ResourceGroupName,
instance.FunctionAppName);
instance.FunctionAppName, cancellationToken);
var configuration = new AggregatorConfiguration
{
DevOpsTokenType = devopsLogonData.Mode,
Expand All @@ -193,7 +193,7 @@ internal async Task<bool> ChangeAppSettings(InstanceName instance, DevOpsLogon d
return true;
}

internal async Task<bool> Remove(InstanceName instance, string location)
internal async Task<bool> RemoveAsync(InstanceName instance, string location)
{
string rgName = instance.ResourceGroupName;
logger.WriteVerbose($"Searching instance {instance.PlainName}...");
Expand Down Expand Up @@ -232,14 +232,14 @@ internal async Task<bool> Remove(InstanceName instance, string location)
return true;
}

internal async Task<bool> ChangeAppSettings(InstanceName instance, string location, SaveMode saveMode)
internal async Task<bool> ChangeAppSettingsAsync(InstanceName instance, string location, SaveMode saveMode, CancellationToken cancellationToken)
{
bool ok;
var devopsLogonData = DevOpsLogon.Load().connection;
if (devopsLogonData.Mode == DevOpsTokenType.PAT)
{
logger.WriteVerbose($"Saving Azure DevOps token");
ok = await ChangeAppSettings(instance, devopsLogonData, saveMode);
ok = await ChangeAppSettingsAsync(instance, devopsLogonData, saveMode, cancellationToken);
logger.WriteInfo($"Azure DevOps token saved");
}
else
Expand All @@ -251,15 +251,15 @@ internal async Task<bool> ChangeAppSettings(InstanceName instance, string locati
}


internal async Task<bool> StreamLogsAsync(InstanceName instance)
internal async Task<bool> StreamLogsAsync(InstanceName instance, CancellationToken cancellationToken)
{
var kudu = new KuduApi(instance, azure, logger);
logger.WriteVerbose($"Connecting to {instance.PlainName}...");

// Main takes care of resetting color
Console.ForegroundColor = ConsoleColor.Green;

await kudu.StreamLogsAsync(Console.Out);
await kudu.StreamLogsAsync(Console.Out, cancellationToken);

return true;
}
Expand Down
10 changes: 6 additions & 4 deletions src/aggregator-cli/Instances/ConfigureInstanceCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace aggregator.cli
Expand All @@ -23,26 +24,27 @@ internal class ConfigureInstanceCommand : CommandBase

[Option('m', "saveMode", SetName = "save", Required = false, HelpText = "Save behaviour.")]
public SaveMode SaveMode { get; set; }

// TODO add --swap.slot to support App Service Deployment Slots


internal override async Task<int> RunAsync()
internal override async Task<int> RunAsync(CancellationToken cancellationToken)
{
var context = await Context
.WithAzureLogon()
.WithDevOpsLogon() // need the token, so we can save it in the app settings
.Build();
.BuildAsync(cancellationToken);
var instances = new AggregatorInstances(context.Azure, context.Logger);
var instance = new InstanceName(Name, ResourceGroup);
bool ok = false;
if (Authentication)
{
ok = await instances.ChangeAppSettings(instance, Location, SaveMode);
ok = await instances.ChangeAppSettingsAsync(instance, Location, SaveMode, cancellationToken);
} else
{
context.Logger.WriteError($"Unsupported command option(s)");
}

return ok ? 0 : 1;
}
}
Expand Down
Loading