Skip to content

Commit

Permalink
feat(new): grafana custom package
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas Maia authored and Jonas Maia committed Apr 11, 2024
1 parent cba0b4d commit c9e52fa
Show file tree
Hide file tree
Showing 14 changed files with 342 additions and 2 deletions.
53 changes: 53 additions & 0 deletions cmf-cli/Commands/new/GrafanaCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Text.Json;
using Cmf.CLI.Constants;
using Cmf.CLI.Core;
using Cmf.CLI.Core.Attributes;
using Cmf.CLI.Core.Enums;
using Cmf.CLI.Core.Objects;
using Cmf.CLI.Utilities;

namespace Cmf.CLI.Commands.New
{
/// <summary>
/// Generates the Grafana folder structure
/// </summary>
[CmfCommand("grafana", ParentId = "new")]
public class GrafanaCommand : LayerTemplateCommand
{
/// <summary>
/// constructor
/// </summary>
public GrafanaCommand() : base("grafana", PackageType.Grafana)
{
}

/// <summary>
/// constructor
/// </summary>
/// <param name="fileSystem"></param>
public GrafanaCommand(IFileSystem fileSystem) : base("grafana", PackageType.Grafana, fileSystem)
{
}

/// <inheritdoc />
protected override List<string> GenerateArgs(IDirectoryInfo projectRoot, IDirectoryInfo workingDir, List<string> args)
{
if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 10)
{
throw new CliException("Version unsupported, available in MES >= 10");
}

var isRepositoryType = ExecutionContext.Instance.ProjectConfig.RepositoryType == RepositoryType.App;

args.AddRange(new[]
{
"--app", isRepositoryType.ToString(),
"--projectName", ExecutionContext.Instance.ProjectConfig.ProjectName.Replace(" ", ""),
});
return args;
}
}
}
1 change: 1 addition & 0 deletions cmf-cli/Factories/PackageTypeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public static IPackageTypeHandler GetPackageTypeHandler(CmfPackage cmfPackage, b
PackageType.Database => new DatabasePackageTypeHandler(cmfPackage),
PackageType.Tests => new TestPackageTypeHandler(cmfPackage),
PackageType.SecurityPortal => SecurityPortalHandler(cmfPackage),
PackageType.Grafana => new GrafanaPackageTypeHandler(cmfPackage),
_ => throw new CliException(string.Format(CoreMessages.PackageTypeHandlerNotImplemented, cmfPackage.PackageType.ToString()))
};

Expand Down
42 changes: 42 additions & 0 deletions cmf-cli/Handlers/PackageType/GrafanaPackageTypeHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Collections.Generic;
using System.Linq;
using Cmf.CLI.Builders;
using Cmf.CLI.Core.Enums;
using Cmf.CLI.Core.Objects;

namespace Cmf.CLI.Handlers
{
/// <summary>
/// Grafana package type handler.
/// </summary>
/// <seealso cref="PackageTypeHandler" />
public class GrafanaPackageTypeHandler : PackageTypeHandler
{
/// <summary>
/// Initializes a new instance of the <see cref="GrafanaPackageTypeHandler" /> class.
/// </summary>
/// <param name="cmfPackage">The CMF package.</param>
public GrafanaPackageTypeHandler(CmfPackage cmfPackage) : base(cmfPackage)
{
cmfPackage.SetDefaultValues
(
targetLayer: "Grafana",
isInstallable: true,
isUniqueInstall: true,
steps: new List<Step>()
{
new(StepType.DeployFiles)
{
ContentPath = "**/**"
},
}
);

IEnumerable<IBuildCommand> buildSteps = cmfPackage.BuildSteps?.Select(pbs => new SingleStepCommand() { BuildStep = pbs } as IBuildCommand);

if (buildSteps != null && buildSteps.Any()) {
BuildSteps = buildSteps.ToArray();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"datatype": "string",
"description": "The custom package name",
"displayName": "Package Name",
"replaces": "<%= $CLI_PARAM_CustomPackageName %>",
"replaces": "<%= $CLI_PARAM_CustomPackageName %>"
//"fileRename": "Feature.Package"
},
"packageVersion": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Critical Manufacturing",
"classifications": [
"cli"
],
"description": "Generate a new Grafana package",
"name": "Grafana Package",
"identity": "cmf-cli.new.grafana",
"groupIdentity": "cmf-cli.new.grafana",
"shortName": "grafana",
"tags": {
"language": "C#",
// Specify that this template is in C#.
"type": "project"
},
"sourceName": "Grafana.Package",
"preferNameDirectory": true,
"symbols": {
"name": {
"type": "parameter",
"datatype": "string",
"description": "The custom package name",
"displayName": "Package Name",
"replaces": "<%= $CLI_PARAM_CustomPackageName %>"
},
"packageVersion": {
"type": "parameter",
"datatype": "string",
"description": "The custom package version",
"displayName": "Package Version",
"replaces": "<%= $CLI_PARAM_CustomPackageVersion %>",
"fileRename": "%version%"
},
"projectName": {
"type": "parameter",
"datatype": "string",
"replaces": "<%= $CLI_PARAM_ProjectName %>",
"fileRename": "%ProjectName%"
},
"app": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "False",
"description": "Indicates that repository type is app if true"
}
},
"sources": [
{
"modifiers": [
{
"condition": "!app",
"exclude": "Grafana.Package/%version%/datasources/criticalmanufacturing-grpc-datasource.json"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: 1

providers:
- name: Default
folder: <%= $CLI_PARAM_ProjectName %>
type: file
options:
path: /etc/grafana/provisioning/dashboards
foldersFromFilesStructure: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id": 1,
"uid": "KHanA1bVk",
"orgId": 1,
"name": "criticalmanufacturing-grpc-datasource",
"type": "criticalmanufacturing-grpc-datasource",
"typeName": "CMF gRPC Datasource",
//keep it?
"typeLogoUrl": "public/plugins/criticalmanufacturing-grpc-datasource/img/logo.svg",
"access": "proxy",
"url": "",
"user": "",
"database": "",
"basicAuth": false,
"isDefault": false,
"jsonData": {
"endpoint": "#uri:port#"
},
"readOnly": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: 1

datasources:
#if (app)
- name: CMF gRPC Datasource
type: criticalmanufacturing-grpc-datasource
uid: #UID#
jsonData:
endpoint: #container-name:port#
#else
~
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"packageId": "<%= $CLI_PARAM_CustomPackageName %>",
"version": "<%= $CLI_PARAM_CustomPackageVersion %>",
"description": "Cmf Custom <%= $CLI_PARAM_ProjectName %> <%= $CLI_PARAM_CustomPackageName %> Package",
"packageType": "Grafana",
"contentToPack": [
{
"source": "$(version)/*",
"target": "",
"ignoreFiles": [
"../.cmfpackageignore"
]
}
]
}
7 changes: 6 additions & 1 deletion core/Enums/PackageType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,10 @@ public enum PackageType
/// The specific product database
/// </summary>
ProductDatabase = 15,

/// <summary>
/// The Grafana
/// </summary>
Grafana = 16,
}
}
}
53 changes: 53 additions & 0 deletions tests/Objects/MockPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,59 @@ namespace tests.Objects
{
internal static class MockPackage
{
internal static readonly MockFileSystem Grafana = new MockFileSystem(new Dictionary<string, MockFileData>
{
{ MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData(
@"{
""ProjectName"": ""MockGrafana"",
""Tenant"": ""MockTenant"",
""MESVersion"": ""10.2.1"",
""NGXSchematicsVersion"": ""1.3.3"",
""RepositoryType"": ""App"",
}")
},
{ MockUnixSupport.Path(@"c:\grafana\1.1.0\dashboards\dashboards.yaml"), new MockFileData(
@"{
apiVersion: 1
providers:
- name: Default
folder: CoolApp
type: file
options:
path: /etc/grafana/provisioning/dashboards
foldersFromFilesStructure: true
}")},
{ MockUnixSupport.Path(@"c:\grafana\1.1.0\datasources\datasources.yaml"), new MockFileData(
@"{
apiVersion: 1
datasources:
~
}")},
{ MockUnixSupport.Path(@"c:\grafana\cmfpackage.json"), new MockFileData(
$@"{{
""packageId"": ""Cmf.Custom.Grafana"",
""version"": ""1.1.0"",
""description"": ""Cmf Custom Grafana Package"",
""packageType"": ""Generic"",
""targetLayer"": ""grafana"",
""isInstallable"": true,
""isUniqueInstall"": true,
""steps"": [
{{
""order"": ""1"",
""type"": ""DeployFiles"",
""ContentPath"": ""**/**""
}}
],
""buildsteps"": [],
""contentToPack"": [
{{
""source"": ""{MockUnixSupport.Path("1.1.0\\*").Replace("\\", "\\\\")}"",
""target"": """"
}}
]
}}")}});

internal static readonly MockFileSystem Html = new MockFileSystem(new Dictionary<string, MockFileData>
{
{ MockUnixSupport.Path(@"c:\.project-config.json"), new MockFileData(
Expand Down
40 changes: 40 additions & 0 deletions tests/Specs/New.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,46 @@ public void Business(BaseLayer layer)
});
}

[Theory]
[InlineData(BaseLayer.Core, RepositoryType.App)]
[InlineData(BaseLayer.MES, RepositoryType.Customization)]
public void Grafana(BaseLayer baseLayer, RepositoryType repositoryType)
{
RunNew(
new GrafanaCommand(),
"Cmf.Custom.Grafana",
mesVersion: "10.2.1",
ngxSchematicsVersion: "1.3.3",
baseLayer: baseLayer,
repositoryType: repositoryType,
extraAsserts: args =>
{
var (pkgVersion, dir) = args;
Assert.True(Directory.Exists("Cmf.Custom.Grafana"), "Grafana package folder is missing");
Assert.True(Directory.Exists($"Cmf.Custom.Grafana/{pkgVersion}"), "Grafana Version folder is missing");
Assert.True(Directory.Exists($"Cmf.Custom.Grafana/{pkgVersion}/dashboards"), "Grafana dashboards folder is missing");
Assert.True(Directory.Exists($"Cmf.Custom.Grafana/{pkgVersion}/datasources"), "Grafana datasources folder is missing");
Assert.True(Directory.Exists($"Cmf.Custom.Grafana/{pkgVersion}/dashboards/CF58AABF/"), "Project Dashboards folder is missing or has wrong name");
Assert.True(File.Exists($"Cmf.Custom.Grafana/{pkgVersion}/dashboards/dashboards.yaml"), "Dashboards configuration file is missing or has wrong name");
Assert.True(File.Exists(
$"Cmf.Custom.Grafana/{pkgVersion}/datasources/datasources.yaml"),
"Datasources configuration file is missing or has wrong name");
if(repositoryType == RepositoryType.App)
{
Assert.True(File.Exists(
$"Cmf.Custom.Grafana/{pkgVersion}/datasources/criticalmanufacturing-grpc-datasource.json"),
"Datamanager datasource file is missing or has wrong name");
}
else
{
Assert.False(File.Exists($"Cmf.Custom.Grafana/{pkgVersion}/datasources/criticalmanufacturing-grpc-datasource.json"));
}
});
}

[Fact]
public void Data()
{
Expand Down
32 changes: 32 additions & 0 deletions tests/Specs/Pack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,38 @@ public void Args_Paths_NoneSpecified()
Assert.False(_force ?? true);
}

[Fact]
public void Grafana()
{
var fileSystem = MockPackage.Grafana;

var packCommand = new PackCommand(fileSystem);
packCommand.Execute(fileSystem.DirectoryInfo.New(MockUnixSupport.Path("c:\\grafana")), fileSystem.DirectoryInfo.New("output"), false);

IEnumerable<IFileInfo> assembledFiles = fileSystem.DirectoryInfo.New("output").EnumerateFiles("Cmf.Custom.Grafana.1.1.0.zip").ToList();
Assert.Single(assembledFiles);

using Stream zipToOpen = fileSystem.FileStream.New(assembledFiles.First().FullName, FileMode.Open);
using (ZipArchive zip = new(zipToOpen, ZipArchiveMode.Read))
{
// these tuples allow us to rewrite entry paths
var entriesToExtract = new List<Tuple<ZipArchiveEntry, string>>();
entriesToExtract.AddRange(zip.Entries.Select(selector: entry => new Tuple<ZipArchiveEntry, string>(entry, entry.FullName)));

List<string> expectedFiles = new()
{
"manifest.xml",
"datasources/datasources.yaml",
"dashboards/dashboards.yaml"
};
Assert.Equal(expectedFiles.Count, entriesToExtract.Count);
foreach (var expectedFile in expectedFiles)
{
Assert.NotNull(entriesToExtract.FirstOrDefault(x => x.Item2.Equals(expectedFile)));
}
}
}

[Fact]
public void HTML()
{
Expand Down

0 comments on commit c9e52fa

Please sign in to comment.