-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from SkylineCommunications/dev/initial
Dev/initial
- Loading branch information
Showing
28 changed files
with
1,615 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: DataMiner CICD NuGet Solution | ||
|
||
# Controls when the workflow will run | ||
on: | ||
# Triggers the workflow on push or pull request events. | ||
push: | ||
branches: [] | ||
tags: | ||
- "[0-9]+.[0-9]+.[0-9]+.[0-9]+" | ||
- "[0-9]+.[0-9]+.[0-9]+" | ||
- "[0-9]+.[0-9]+.[0-9]+.[0-9]+-**" | ||
- "[0-9]+.[0-9]+.[0-9]+-**" | ||
|
||
# Allows you to run this workflow manually from the Actions tab | ||
workflow_dispatch: | ||
|
||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel | ||
jobs: | ||
|
||
# Note: Tagging will push the nupackage to nuget.org using the provided NUGETAPIKEY. You can tag both a prerelease version (a.b.c-xxxx) or a stable release (a.b.c). | ||
CICD: | ||
uses: SkylineCommunications/_ReusableWorkflows/.github/workflows/NuGet Solution Master Workflow.yml@main | ||
with: | ||
referenceName: ${{ github.ref_name }} | ||
runNumber: ${{ github.run_number }} | ||
referenceType: ${{ github.ref_type }} | ||
repository: ${{ github.repository }} | ||
owner: ${{ github.repository_owner }} | ||
sonarCloudProjectName: SkylineCommunications_Skyline.DataMiner.CICD.Tools.CatalogUpload | ||
secrets: | ||
sonarCloudToken: ${{ secrets.SONAR_TOKEN }} | ||
pfx: ${{ secrets.PFX }} | ||
pfxPassword: ${{ secrets.PFXPASSWORD }} | ||
nugetApiKey: ${{ secrets.NUGETAPIKEY }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
CICD.Tools.CatalogUpload.Lib/CICD.Tools.CatalogUpload.Lib.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>disable</ImplicitUsings> | ||
<Nullable>disable</Nullable> | ||
<AssemblyName>Skyline.DataMiner.CICD.Tools.CatalogUpload.Lib</AssemblyName> | ||
<PackageVersion>1.0.1-alpaha1</PackageVersion> | ||
<Version>1.0.1-alpaha1</Version> | ||
<PackageTags>Skyline;DataMiner</PackageTags> | ||
<PackageProjectUrl>https://skyline.be</PackageProjectUrl> | ||
<PackageReadmeFile>README.md</PackageReadmeFile> | ||
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile> | ||
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> | ||
<PackageIcon>Icon.png</PackageIcon> | ||
<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> | ||
<Authors>SkylineCommunications</Authors> | ||
<Company>Skyline Communications</Company> | ||
<Description> | ||
Library containing code to upload artifacts to the Skyline DataMiner Catalog (https://catalog.dataminer.services/). | ||
Entry Point: new CatalogArtifact("pathToArtifact", "logger", "metaData").UploadAsync(); | ||
</Description> | ||
<RootNamespace>Skyline.DataMiner.CICD.Tools.CatalogUpload.Lib</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<None Include="README.md" Pack="true" PackagePath="" /> | ||
<None Include="LICENSE.txt" Pack="true" PackagePath="" /> | ||
<None Include="nuget\Icon.png" Pack="true" PackagePath="" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||
<PackageReference Include="Skyline.DataMiner.CICD.FileSystem" Version="1.0.2-ReadAllBytes1" /> | ||
<PackageReference Include="Skyline.DataMiner.CICD.Tools.WinEncryptedKeys.Lib" Version="1.0.2" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
namespace Skyline.DataMiner.CICD.Tools.CatalogUpload.Lib | ||
{ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
using Microsoft.Extensions.Logging; | ||
|
||
using Newtonsoft.Json; | ||
|
||
using Skyline.DataMiner.CICD.FileSystem; | ||
|
||
/// <summary> | ||
/// Allows Uploading an artifact to the Catalog using one of the below in order of priority: | ||
/// <para>- provided key in upload argument (Unix/Windows)</para> | ||
/// <para>- key stored as an Environment Variable called "DATAMINER_CATALOG_TOKEN". (Unix/Windows)</para> | ||
/// <para>- key configured using Skyline.DataMiner.CICD.Tools.WinEncryptedKeys called "DATAMINER_CATALOG_TOKEN_ENCRYPTED" (Windows only)</para> | ||
/// </summary> | ||
public class CatalogArtifact | ||
{ | ||
private readonly ILogger _logger; | ||
private readonly CatalogMetaData metaData; | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="CatalogArtifact"/>. | ||
/// It searches for an optional dmCatalogToken in the "DATAMINER_CATALOG_TOKEN" or "DATAMINER_CATALOG_TOKEN_ENCRYPTED" Environment Variable. | ||
/// </summary> | ||
/// <param name="pathToArtifact">Path to the application package (.dmapp) or protocol package (.dmprotocol).</param> | ||
/// <param name="service">An instance of <see cref="ICatalogService"/> used for communication.</param> | ||
/// <param name="fileSystem">An instance of <see cref="IFileSystem"/> to access the filesystem. e.g. Skyline.DataMiner.CICD.FileSystem.Instance.</param> | ||
/// <param name="logger">An instance of <see cref="ILogger"/> that will hold error, debug and other information.</param> | ||
/// <param name="metaData">Contains package metadata.</param> | ||
public CatalogArtifact(string pathToArtifact, ICatalogService service, IFileSystem fileSystem, ILogger logger, CatalogMetaData metaData) | ||
{ | ||
this.metaData = metaData; | ||
_logger = logger; | ||
Fs = fileSystem; | ||
cancellationTokenSource = new CancellationTokenSource(); | ||
catalogService = service; | ||
PathToArtifact = pathToArtifact; | ||
TryFindEnvironmentKey(); | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="CatalogArtifact"/> using a default HttpCatalogService with a new HttpClient for communication. | ||
/// It searches for an optional dmCatalogToken in the "DATAMINER_CATALOG_TOKEN" or "DATAMINER_CATALOG_TOKEN_ENCRYPTED" Environment Variable for authentication. | ||
/// </summary> | ||
/// <remarks>WARNING: when wishing to upload several Artifacts it's recommended to use the CatalogArtifact(string pathToArtifact, ICatalogService service, IFileSystem fileSystem, ILogger logger).</remarks> | ||
/// <param name="pathToArtifact">Path to the application package (.dmapp) or protocol package (.dmprotocol).</param> | ||
/// <param name="logger">An instance of <see cref="ILogger"/> that will hold error, debug and other information.</param> | ||
/// <param name="metaData">Contains package metadata.</param> | ||
public CatalogArtifact(string pathToArtifact, ILogger logger, CatalogMetaData metaData) : this(pathToArtifact, CatalogServiceFactory.CreateWithHttp(new System.Net.Http.HttpClient(), logger), FileSystem.Instance, logger, metaData) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Path to the application package (.dmapp) or protocol package (.dmprotocol). | ||
/// </summary> | ||
public string PathToArtifact { get; private set; } | ||
|
||
private CancellationTokenSource cancellationTokenSource { get; set; } | ||
|
||
private ICatalogService catalogService { get; set; } | ||
|
||
private IFileSystem Fs { get; set; } | ||
|
||
private string keyFromEnv { get; set; } | ||
|
||
/// <summary> | ||
/// Cancels an ongoing upload. Create a new CatalogArtifact to attempt a new upload. | ||
/// </summary> | ||
public void CancelUpload() | ||
{ | ||
_logger.LogDebug($"Upload cancellation requested for {PathToArtifact}"); | ||
cancellationTokenSource.Cancel(); | ||
} | ||
|
||
/// <summary> | ||
/// Uploads to the private catalog using the provided dmCatalogToken. | ||
/// </summary> | ||
/// <param name="dmCatalogToken">A provided token for the agent or organization as defined in https://admin.dataminer.services/.</param> | ||
/// <returns>If the upload was successful or not.</returns> | ||
public async Task<ArtifactUploadResult> UploadAsync(string dmCatalogToken) | ||
{ | ||
if(dmCatalogToken != keyFromEnv) | ||
{ | ||
_logger.LogDebug($"Attempting upload with provided argument as token for artifact: {PathToArtifact}..."); | ||
} | ||
|
||
_logger.LogDebug($"Uploading {PathToArtifact}..."); | ||
|
||
byte[] packageData = Fs.File.ReadAllBytes(PathToArtifact); | ||
var result = await catalogService.ArtifactUploadAsync(packageData, dmCatalogToken, metaData, cancellationTokenSource.Token).ConfigureAwait(false); | ||
_logger.LogDebug($"Finished Uploading {PathToArtifact}"); | ||
|
||
_logger.LogInformation(JsonConvert.SerializeObject(result)); | ||
return result; | ||
} | ||
|
||
/// <summary> | ||
/// Uploads to the private catalog using the DATAMINER_CATALOG_TOKEN or DATAMINER_CATALOG_TOKEN environment variable as the token. | ||
/// </summary> | ||
/// <returns>If the upload was successful or not.</returns> | ||
/// <exception cref="InvalidOperationException">Uploading failed.</exception> | ||
/// <exception cref="UnauthorizedAccessException">Uploading failed due to invalid Token.</exception> | ||
public async Task<ArtifactUploadResult> UploadAsync() | ||
{ | ||
if (String.IsNullOrWhiteSpace(keyFromEnv)) | ||
{ | ||
throw new InvalidOperationException("Uploading failed, missing token in environment variable DATAMINER_CATALOG_TOKEN or DATAMINER_CATALOG_TOKEN_ENCRYPTED."); | ||
} | ||
|
||
_logger.LogDebug($"Attempting upload with Environment Variable as token for artifact: {PathToArtifact}..."); | ||
return await UploadAsync(keyFromEnv).ConfigureAwait(false); | ||
} | ||
|
||
/// <summary> | ||
/// Attempts to find the necessary API key in Environment Variables. In order of priority: | ||
/// <para>- key stored as an Environment Variable called "DATAMINER_CATALOG_TOKEN". (unix/win)</para> | ||
/// <para>- key configured using Skyline.DataMiner.CICD.Tools.WinEncryptedKeys called "DATAMINER_CATALOG_TOKEN_ENCRYPTED" (windows only)</para> | ||
/// </summary> | ||
private void TryFindEnvironmentKey() | ||
{ | ||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||
{ | ||
try | ||
{ | ||
var encryptedKey = WinEncryptedKeys.Lib.Keys.RetrieveKey("DATAMINER_CATALOG_TOKEN_ENCRYPTED"); | ||
if (encryptedKey != null) | ||
{ | ||
string keyFromWinEncryptedKeys = new System.Net.NetworkCredential(string.Empty, encryptedKey).Password; | ||
|
||
if (!String.IsNullOrWhiteSpace(keyFromWinEncryptedKeys)) | ||
{ | ||
_logger.LogDebug("OK: Found token in Env Variable: 'DATAMINER_CATALOG_TOKEN_ENCRYPTED' created by WinEncryptedKeys."); | ||
keyFromEnv = keyFromWinEncryptedKeys; | ||
} | ||
} | ||
} | ||
catch (InvalidOperationException) | ||
{ | ||
// Gobble up, no key means we try the next thing. | ||
} | ||
} | ||
|
||
//var config = new ConfigurationBuilder() | ||
// .AddUserSecrets<CatalogArtifact>() | ||
// .Build(); | ||
//string keyFromEnvironment = config["DATAMINER_CATALOG_TOKEN"]; | ||
|
||
string keyFromEnvironment = Environment.GetEnvironmentVariable("DATAMINER_CATALOG_TOKEN"); | ||
|
||
if (!String.IsNullOrWhiteSpace(keyFromEnvironment)) | ||
{ | ||
if (!String.IsNullOrWhiteSpace(keyFromEnv)) | ||
{ | ||
_logger.LogDebug("OK: Overriding 'DATAMINER_CATALOG_TOKEN_ENCRYPTED' with found token in Env Variable: 'DATAMINER_CATALOG_TOKEN'."); | ||
} | ||
else | ||
{ | ||
_logger.LogDebug("OK: Found token in Env Variable: 'DATAMINER_CATALOG_TOKEN'."); | ||
} | ||
|
||
keyFromEnv = keyFromEnvironment; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.