-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dev/initial #1
Dev/initial #1
Changes from all commits
fb73112
e48518b
a932b8e
088d094
c228e8c
16f754b
d767e50
09d1628
229a3c8
3a49ced
50a582a
cdf7af7
df72ae7
d3f4f12
4b5c98f
e899b64
e227ca6
4897357
a2cb6c6
95d62f1
47c7974
583cd52
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 }} |
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> |
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// </summary> | ||||||
/// <param name="dmCatalogToken">A provided token for the agent or organization as defined in https://admin.dataminer.services/.</param> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// <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> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// <exception cref="UnauthorizedAccessException">Uploading failed due to invalid Token.</exception> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
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() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove commented out code |
||||||
// .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; | ||||||
} | ||||||
} | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
///
/// Path to the application package (.dmapp) or protocol package (.dmprotocol).