Arg and env-var parsing

This commit is contained in:
benbierens 2023-06-22 09:51:25 +02:00
parent 40046d9bcb
commit e5a7f04c4e
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
4 changed files with 218 additions and 2 deletions

View File

@ -0,0 +1,89 @@
namespace CodexNetDeployer
{
public class ArgOrVar
{
public static readonly ArgVar CodexImage = new ArgVar("codex-image", "CODEXIMAGE", "Docker image of Codex.");
public static readonly ArgVar GethImage = new ArgVar("geth-image", "GETHIMAGE", "Docker image of Geth.");
public static readonly ArgVar ContractsImage = new ArgVar("contracts-image", "CONTRACTSIMAGE", "Docker image of Codex Contracts deployer.");
public static readonly ArgVar KubeConfigFile = new ArgVar("kube-config", "KUBECONFIG", "Path to Kubeconfig file.");
public static readonly ArgVar KubeNamespace = new ArgVar("kube-namespace", "KUBENAMESPACE", "Kubernetes namespace to be used for deployment.");
public static readonly ArgVar NumberOfCodexNodes = new ArgVar("nodes", "NODES", "Number of Codex nodes to be created.");
public static readonly ArgVar StorageQuota = new ArgVar("storage-quota", "STORAGEQUOTA", "Storage quota in megabytes used by each Codex node.");
private readonly string[] args;
public ArgOrVar(string[] args)
{
this.args = args;
}
public string Get(ArgVar key, string defaultValue = "")
{
var argKey = $"--{key.Arg}=";
var arg = args.FirstOrDefault(a => a.StartsWith(argKey));
if (arg != null)
{
return arg.Substring(argKey.Length);
}
var env = Environment.GetEnvironmentVariable(key.Var);
if (env != null)
{
return env;
}
return defaultValue;
}
public int? GetInt(ArgVar key)
{
var str = Get(key);
if (string.IsNullOrEmpty(str)) return null;
if (int.TryParse(str, out int result))
{
return result;
}
return null;
}
public void PrintHelp()
{
var nl = Environment.NewLine;
Console.WriteLine("CodexNetDeployer allows you to easily deploy multiple Codex nodes in a Kubernetes cluster. " +
"The deployer will set up the required supporting services, deploy the Codex on-chain contracts, start and bootstrap the Codex instances. " +
"All Kubernetes objects will be created in the namespace provided, allowing you to easily find, modify, and delete them afterwards." + nl);
Console.Write("\t[ CLI argument ] or [ Environment variable ]");
Console.CursorLeft = 70;
Console.Write("(Description)" + nl);
var fields = GetType().GetFields();// System.Reflection.BindingFlags.Public & System.Reflection.BindingFlags.Static);
foreach (var field in fields)
{
var value = (ArgVar)field.GetValue(null)!;
value.PrintHelp();
}
}
}
public class ArgVar
{
public ArgVar(string arg, string var, string description)
{
Arg = arg;
Var = var;
Description = description;
}
public string Arg { get; }
public string Var { get; }
public string Description { get; }
public void PrintHelp()
{
Console.Write($"\t[ --{Arg}=... ] or [ {Var}=... ]");
Console.CursorLeft = 70;
Console.Write(Description + Environment.NewLine);
}
}
}

View File

@ -7,4 +7,8 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DistTestCore\DistTestCore.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,84 @@
namespace CodexNetDeployer
{
public class Configuration
{
public Configuration(
string codexImage,
string gethImage,
string contractsImage,
string kubeConfigFile,
string kubeNamespace,
int? numberOfCodexNodes,
int? storageQuota)
{
CodexImage = codexImage;
GethImage = gethImage;
ContractsImage = contractsImage;
KubeConfigFile = kubeConfigFile;
KubeNamespace = kubeNamespace;
NumberOfCodexNodes = numberOfCodexNodes;
StorageQuota = storageQuota;
}
public string CodexImage { get; }
public string GethImage { get; }
public string ContractsImage { get; }
public string KubeConfigFile { get; }
public string KubeNamespace { get; }
public int? NumberOfCodexNodes { get; }
public int? StorageQuota { get; }
public void PrintConfig()
{
ForEachProperty(onString: Print, onInt: Print);
}
public List<string> Validate()
{
var errors = new List<string>();
ForEachProperty(
onString: (n, v) => StringIsSet(n, v, errors),
onInt: (n, v) => IntIsOverZero(n, v, errors));
return errors;
}
private void ForEachProperty(Action<string, string> onString, Action<string, int?> onInt)
{
var properties = GetType().GetProperties();
foreach (var p in properties)
{
if (p.PropertyType == typeof(string)) onString(p.Name, (string)p.GetValue(this)!);
if (p.PropertyType == typeof(int?)) onInt(p.Name, (int?)p.GetValue(this)!);
}
}
private static void IntIsOverZero(string variable, int? value, List<string> errors)
{
if (value == null || value.Value < 1)
{
errors.Add($"{variable} is must be set and must be greater than 0.");
}
}
private static void StringIsSet(string variable, string value, List<string> errors)
{
if (string.IsNullOrWhiteSpace(value))
{
errors.Add($"{variable} is must be set.");
}
}
private static void Print(string variable, string value)
{
Console.WriteLine($"\t{variable}: '{value}'");
}
private static void Print(string variable, int? value)
{
if (value != null) Print(variable, value.ToString()!);
else Print(variable, "<NONE>");
}
}
}

View File

@ -1,7 +1,46 @@
public class Program using CodexNetDeployer;
using DistTestCore.Codex;
using DistTestCore.Marketplace;
public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
Console.WriteLine("Hello, World!"); var nl = Environment.NewLine;
Console.WriteLine("CodexNetDeployer" + nl + nl);
var argOrVar = new ArgOrVar(args);
if (args.Any(a => a == "-h" || a == "--help" || a == "-?"))
{
argOrVar.PrintHelp();
return;
}
var config = new Configuration(
codexImage: argOrVar.Get(ArgOrVar.CodexImage, CodexContainerRecipe.DockerImage),
gethImage: argOrVar.Get(ArgOrVar.GethImage, GethContainerRecipe.DockerImage),
contractsImage: argOrVar.Get(ArgOrVar.ContractsImage, CodexContractsContainerRecipe.DockerImage),
kubeConfigFile: argOrVar.Get(ArgOrVar.KubeConfigFile),
kubeNamespace: argOrVar.Get(ArgOrVar.KubeNamespace),
numberOfCodexNodes: argOrVar.GetInt(ArgOrVar.NumberOfCodexNodes),
storageQuota: argOrVar.GetInt(ArgOrVar.StorageQuota)
);
Console.WriteLine("Using:");
config.PrintConfig();
Console.WriteLine(nl);
var errors = config.Validate();
if (errors.Any())
{
Console.WriteLine($"Configuration errors: ({errors.Count})");
foreach ( var error in errors ) Console.WriteLine("\t" + error);
Console.WriteLine(nl);
argOrVar.PrintHelp();
return;
}
} }
} }