Skip to content

Commit

Permalink
Release/1.0.0 (#186)
Browse files Browse the repository at this point in the history
* fix bug local map URL

* better diagnostic

* Aggregator_AzureDevOpsCertificate to trust from container

* fix some issues with API key
  • Loading branch information
giuliov authored Sep 17, 2020
1 parent 0f2e1bd commit dbdf4b5
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 20 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
**/.vscode
**/*.zip
docker/
!docker/*.exe
!docker/*.cmd
!docker/*.sh
!docker/*.pem
outputs/
marketplace/
src/.build-trigger
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ src/aggregator-function/test*/*
src/aggregator-cli/FunctionRuntime.zip
.DS_Store
*.exe
!docker/certoc.exe
*.diagsession
*.vsix
*.rdp
Expand Down
13 changes: 10 additions & 3 deletions Next-Release-ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
This is the final **Release Candidate** version.
This is the inital **1.0** release.

CLI Commands and Options
========================
* Resolve code analysis warnings.
* Fix incorrect HTTP Header in web hook Subscriptions made by `map.local.rule`.
* Fix incorrect URL in web hook Subscriptions made by `map.local.rule`.


Docker and Azure Function Hosting
========================
* Resolve code analysis warnings.
* Fix error CS1705
* Fix CS1705 error.
* Support for `Aggregator_AzureDevOpsCertificate` when Azure DevOps is using a certificate issued by non-trusted Certification Authority (e.g.self-signed).
* Better handling of API keys.


Rule Language
========================
* optional `events` directive
* New optional `events` directive.


Rule Interpreter Engine
========================
* Resolve code analysis warnings.
* Improved some messages.


Build, Test, Documentation
Expand All @@ -29,6 +33,9 @@ Build, Test, Documentation
* Resolve code analysis warnings.
* Fix default branch reference in CI workflow.
* Push docker images to GitHub Container Registry (beta) in addition to Docker Hub.
* Local version number is now `0.0.1-localdev`.
* Fix build badge, added SonarQube badge.
* Trimmed `.dockerignore`.


File Hashes
Expand Down
Binary file added docker/certoc.exe
Binary file not shown.
7 changes: 6 additions & 1 deletion docker/linux-x64.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ ENV Aggregator_ApiKeysPath=/secrets/apikeys.json
ENV Logging__LogLevel__Aggregator=Debug
ENV ASPNETCORE_URLS=https://*:5320
ENV AGGREGATOR_TELEMETRY_DISABLED=false
ENV Aggregator_AzureDevOpsCertificate=

EXPOSE 5320/tcp

ENTRYPOINT [ "dotnet", "aggregator-host.dll" ]
COPY ./docker/start.sh /app/start.sh
RUN chmod +x /app/start.sh

ENTRYPOINT /app/start.sh
#ENTRYPOINT [ "dotnet", "aggregator-host.dll" ]
21 changes: 21 additions & 0 deletions docker/start.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@ECHO OFF

REM Bypass "Terminate Batch Job" prompt.
if "%~1"=="-FIXED_CTRL_C" (
REM Remove the -FIXED_CTRL_C parameter
SHIFT
) ELSE (
REM Run the batch with <NUL and -FIXED_CTRL_C
CALL <NUL %0 -FIXED_CTRL_C %*
GOTO :EOF
)

IF EXIST "%Aggregator_AzureDevOpsCertificate%" (
ECHO Importing %Aggregator_AzureDevOpsCertificate%
certoc -addstore root "%Aggregator_AzureDevOpsCertificate%"
ECHO Import completed
ECHO.
)
dotnet aggregator-host.dll

EXIT
10 changes: 10 additions & 0 deletions docker/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
if [ -f "/secrets/$Aggregator_AzureDevOpsCertificate" ]; then
echo Importing $Aggregator_AzureDevOpsCertificate
#mkdir /usr/local/share/ca-certificates/extra
#cp /secrets/$Aggregator_AzureDevOpsCertificate /usr/local/share/ca-certificates/extra
cp /secrets/$Aggregator_AzureDevOpsCertificate /usr/local/share/ca-certificates/$Aggregator_AzureDevOpsCertificate
update-ca-certificates
echo Import completed
fi
dotnet aggregator-host.dll
6 changes: 5 additions & 1 deletion docker/win-x64.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ VOLUME c:/secrets
ENV Aggregator_VstsTokenType=PAT
ENV Aggregator_VstsToken=
ENV Aggregator_RulesPath=c:\rules
ENV Aggregator_AzureDevOpsCertificate=
ENV ASPNETCORE_Kestrel__Certificates__Default__Path=c:\secrets\aggregator.pfx
ENV Aggregator_ApiKeysPath=c:\secrets\apikeys.json
ENV Logging__LogLevel__Aggregator=Debug
Expand All @@ -49,5 +50,8 @@ EXPOSE 5320/tcp
# https://github.com/dotnet/dotnet-docker/issues/915
USER ContainerAdministrator

ENTRYPOINT [ "dotnet", "aggregator-host.dll" ]
COPY ./docker/certoc.exe .
COPY ./docker/start.cmd .

ENTRYPOINT [ "start.cmd" ]

8 changes: 4 additions & 4 deletions src/aggregator-cli/Instances/FunctionRuntimePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ internal FunctionRuntimePackage(ILogger logger)

if (gitHubVersion == null || string.IsNullOrEmpty(gitHubVersion.Name))
{
logger.WriteError($"Requested version does not exist.");
logger.WriteError($"Requested CLI version does not exist in GitHub.");
return (upgrade: false, newversion: "");
}
logger.WriteVerbose($"Found {gitHubVersion.Name} on {gitHubVersion.When} in GitHub .");
logger.WriteVerbose($"Found {gitHubVersion.Name} on {gitHubVersion.When} in GitHub.");

SemVersion.TryParse(gitHubVersion.Name.Substring(1), out var latest);
var current = new SemVersion(
Expand Down Expand Up @@ -260,7 +260,7 @@ string GitHubTagFromUserVersion(string requiredVersion)

if (gitHubVersion == null || string.IsNullOrEmpty(gitHubVersion.Name))
{
logger.WriteError($"Requested runtime {requiredVersion} version does not exist.");
logger.WriteError($"Requested runtime {requiredVersion} version does not exist in GitHub.");
return (null, null);
}
logger.WriteVerbose($"Found {gitHubVersion.Name} on {gitHubVersion.When} in GitHub .");
Expand Down Expand Up @@ -289,7 +289,7 @@ internal async Task<SemVersion> GetDeployedRuntimeVersion(InstanceName instance,
}
else
{
logger.WriteWarning($"Cannot read aggregator-manifest.ini: {response.ReasonPhrase}");
logger.WriteWarning($"Cannot read aggregator-manifest.ini: {response.ReasonPhrase} (disregard this message on new instances)");
uploadedRuntimeVer = new SemVersion(0, 0, 0);
}
}
Expand Down
17 changes: 12 additions & 5 deletions src/aggregator-cli/Mappings/AggregatorMappings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,15 @@ internal async Task<Guid> AddFromUrlAsync(string projectName, string @event, Eve
{
async Task<(Uri, string)> RetrieveHostedUrl(string _ruleName, CancellationToken _cancellationToken)
{
string apiKey = "INVALID";
string apiKey = MagicConstants.InvalidApiKey;

logger.WriteVerbose($"Validating target URL {targetUrl.AbsoluteUri}");

string userManagedPassword = Environment.GetEnvironmentVariable("Aggregator_SharedSecret");
string userManagedPassword = Environment.GetEnvironmentVariable(MagicConstants.EnvironmentVariable_SharedSecret);
if (string.IsNullOrEmpty(userManagedPassword))
{
throw new ApplicationException($"{MagicConstants.EnvironmentVariable_SharedSecret} environment variable is required for this command");
}

string proof = SharedSecret.DeriveFromPassword(userManagedPassword);

Expand All @@ -115,7 +119,7 @@ internal async Task<Guid> AddFromUrlAsync(string projectName, string @event, Eve
switch (response.StatusCode)
{
case HttpStatusCode.OK:
logger.WriteVerbose($"Connected to {targetUrl}");
logger.WriteVerbose($"Connection to {targetUrl} succeded");
apiKey = await response.Content.ReadAsStringAsync();
logger.WriteInfo($"Configuration retrieved.");
break;
Expand All @@ -127,10 +131,13 @@ internal async Task<Guid> AddFromUrlAsync(string projectName, string @event, Eve
}
}

logger.WriteInfo($"Target URL is working");
if (string.IsNullOrEmpty(apiKey) || apiKey == MagicConstants.InvalidApiKey)
{
throw new ApplicationException("Unable to retrieve API Key, please check Shared secret configuration");
}

var b = new UriBuilder(targetUrl);
b.Path += $"/workitem/{_ruleName}";
b.Path += $"workitem/{_ruleName}";
return (b.Uri, apiKey);
}

Expand Down
16 changes: 12 additions & 4 deletions src/aggregator-host/Controllers/ConfigController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System;
using System.Text.Json;
using aggregator;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand Down Expand Up @@ -48,15 +49,22 @@ public string RetrieveKey([FromBody] JsonElement body)
_log.LogDebug("RetrieveKey method was called!");

string proof = body.GetString();
string userManagedPassword = _configuration.GetValue<string>("Aggregator_SharedSecret");
string userManagedPassword = _configuration.GetValue<string>(MagicConstants.EnvironmentVariable_SharedSecret);
if (string.IsNullOrEmpty(userManagedPassword))
{
throw new ApplicationException($"{MagicConstants.EnvironmentVariable_SharedSecret} environment variable is required by CLI");
}

if (proof == SharedSecret.DeriveFromPassword(userManagedPassword))
{
return _apiKeyRepo.PickValidKey();
}
else
{
_log.LogError("API Key request failed from {0}", HttpContext.Connection.RemoteIpAddress);
return MagicConstants.InvalidApiKey;

return "OK";

}
}
}
}
15 changes: 13 additions & 2 deletions src/aggregator-ruleng/RuleExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,19 @@ private async Task<string> ExecAsyncImpl(IRule rule, WorkItemEventContext eventC

// TODO improve from https://github.com/Microsoft/vsts-work-item-migrator
using var devops = new VssConnection(eventContext.CollectionUri, clientCredentials);
await devops.ConnectAsync(cancellationToken);
logger.WriteInfo($"Connected to Azure DevOps");
try
{
await devops.ConnectAsync(cancellationToken);
logger.WriteInfo($"Connected to Azure DevOps");
}
catch (System.Exception ex)
{
logger.WriteError(ex.Message);
if (ex.InnerException != null) {
logger.WriteError(ex.InnerException.Message);
}
throw ex;
}
using var clientsContext = new AzureDevOpsClientsContext(devops);
var engine = new RuleEngine(logger, configuration.SaveMode, configuration.DryRun);

Expand Down
2 changes: 2 additions & 0 deletions src/aggregator-shared/MagicConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ public static class MagicConstants
{
public const string LoggerCategoryName = "Aggregator";
public const string ApiKeyAuthenticationHeaderName = "X-Auth-ApiKey";
public const string InvalidApiKey = "INVALID";
#pragma warning disable S1075 // URIs should not be hardcoded
public const string MissingUrl = "https://this.should.never.come.up.example.com/";
#pragma warning restore S1075 // URIs should not be hardcoded
public const string EnvironmentVariable_SharedSecret = "Aggregator_SharedSecret";
}
}

0 comments on commit dbdf4b5

Please sign in to comment.