diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs index 24d96a3..5ddf79f 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs @@ -157,7 +157,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS if (defaultvalue != null) { prompt += $" Default value is '{defaultvalue}'."; } if (exitvalue != null) { prompt += $" Enter '{exitvalue}' to exit."; } - WriteLine(text, f, b, bracket, prefix, suffix); + Write(text, f, b, bracket, prefix, suffix); + if (!string.IsNullOrWhiteSpace(text+bracket+prefix+suffix)) WriteLine(); if (prompt != null) { WriteLine(prompt); } Write("-->"); input = Console.ReadLine(); if (defaultvalue!=null && (input == null || input == "")) { input = defaultvalue; } diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs index 7c9ad89..338bd99 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs @@ -328,6 +328,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS public static class StartAsSystem { public const string KEY = "SAS"; } public static class RegexTester { public const string KEY = "RGX"; } public static class TCPIPTester { public const string KEY = "TCP"; } + public static class ASEConfig { public const string KEY = "ACF"; } public static class Tool { public const string KEY = "TOL"; } } } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs index 5e2a452..ffdf258 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs @@ -42,7 +42,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.StartAsSystem.KEY, "Start As NT AUTHORITY/SYSTEM", StartAsSystem, new Menu.ExecutorParameter(cfg: config))) .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.RegexTester.KEY, "Regex tester", RegexTester,new Menu.ExecutorParameter(cfg:config))) .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.TCPIPTester.KEY, "TcpIp Tester", TcpIpTester, new Menu.ExecutorParameter(cfg: config, null))) - .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.Tool.KEY, "Tool sample", Tool2, new Menu.ExecutorParameter(cfg: config, null))) + .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.ASEConfig.KEY, "ASEConfig Utility", AseConfig, new Menu.ExecutorParameter(cfg: config, null))) + //.AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.Tool.KEY, "Tool sample", Tool, new Menu.ExecutorParameter(cfg: config, null))) .SetSelectionMode(Menu.SelectionMode.Single); foreach (var x in config.ExternalUtilityConfigList) @@ -81,7 +82,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS private static object RegexTester(object parameter, object o) { var config = (parameter as Menu.ExecutorParameter).GetConfig(); - var regexptesterconfig = config.RegexpTesterConfig; + var regexptesterconfig = config.RegexpTesterConfigXml; while(true) { var regexstr = ColorConsole.ReadLine($"Enter REGEX to test with:", ConsoleColor.Yellow); @@ -364,12 +365,255 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS #endregion TcpIpTester + #region ASEConfig + private static object AseConfig(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var CommandXmlList = config.ASEConfigXml.Elements(XName.Get("Command")); + if (CommandXmlList == null) return o; + List aseconfigcommandList = new List(); + foreach (var commandXml in CommandXmlList) { aseconfigcommandList.Add(new ASEConfigCommand(commandXml)); } + var selectedkey = SelectAseConfigCommand(aseconfigcommandList); + if (selectedkey == null) return o; + var selectedcommand = aseconfigcommandList.FirstOrDefault(c=>c.EqualsTo(selectedkey)); + if (selectedcommand == null) return o; + selectedcommand.Ini(); + if (!selectedcommand.SetArgumentParameters()) return o;//a paraméterek interaktív értékeit kéri be + if (!selectedcommand.DisplayArgumentParameters()) return o; + foreach (string currentip in selectedcommand.GetIpList()) + { + ColorConsole.WriteLine($"Processing IP:{currentip}", ConsoleColor.Yellow); + var success = selectedcommand.Resolve(currentip);//feloldja az argument listát + if (success) { selectedcommand.Execute(); }//végrehajtja a parancsot } + string successmsg = success ? "succeeded" : "failed"; + string answer = ColorConsole.ReadLine($"{nameof(AseConfig)} command execution {successmsg} on {currentip}!\nEnter EX to exit from execution loop, anything else to continue!", success?ConsoleColor.Yellow: ConsoleColor.Red); + if (answer.ToLower() == "ex") break; + } + return o; + } + private static string SelectAseConfigCommand(List aseconfigcommandList) + { + ColorConsole.WriteLine("ASEConfig Utility",ConsoleColor.Green); + int maxkeylength = aseconfigcommandList.Select(c => c.Key.Length).Concat(new List { 0}).Max(); + int maxdesclength = aseconfigcommandList.Select(c => c.Description.Length).Concat(new List { 0 }).Max(); + + foreach (var c in aseconfigcommandList) + { + var onelineinfo = c.GetOneLineInfo(maxkeylength, maxdesclength); + ColorConsole.Write(onelineinfo.Item1, ConsoleColor.Yellow,suffix:" "); + ColorConsole.Write(onelineinfo.Item2, ConsoleColor.White, suffix: " "); + ColorConsole.WriteLine(onelineinfo.Item3, ConsoleColor.Gray); + } + var answer = ColorConsole.ReadLine($"Select command key", ConsoleColor.Gray, bracket: "[]",validitylist: aseconfigcommandList.Select(c => c.Key).ToList()); + if (answer.ToLower() == "ex") return null; + return answer; + } + private class ASEConfigCommand + { + private enum CommandType { export,import,importnoanswer, exportpartial,} + public ASEConfigCommand(XElement commandXml) + { + const string DEFAULTIMPORTARGUMENTS = "-u {ASEUSERNAME}:{ASEPASSWORD} -X POST --form configrecord=\"@{CONFIGFILE}\" http://{ASEIP}/import/config"; + const string DEFAULTIMPORTNOANSWERARGUMENTS = "-u {ASEUSERNAME}:{ASEPASSWORD} -X POST --form configrecord=\"@{CONFIGFILE}\" http://{ASEIP}/import/config -m 5"; + const string DEFAULTEXPORTARGUMENTS = "-u {ASEUSERNAME}:{ASEPASSWORD} -X POST http://{ASEIP}/export/config -o ASECONFIG-{ASEIP}.xml"; + const string DEFAULTEXPORTPARTIALARGUMENTS = "-u {ASEUSERNAME}:{ASEPASSWORD} -X POST -d \"optionalGroupList = {CONFIGGROUPNAME}:{CONFIGGROUPINSTANCE}\" http://{ASEIP}/export/config -o ASECONFIG-{ASEIP}.xml"; + var typestr = (commandXml.Attribute(XName.Get(nameof(Type)))?.Value)??nameof(CommandType.import); + Type = CommandType.import; try { Type = (CommandType)Enum.Parse(typeof(CommandType),typestr); } catch { } + + ConfigGroupName = commandXml.Attribute(XName.Get(nameof(ConfigGroupName)))?.Value; + ConfigGroupInstance = commandXml.Attribute(XName.Get(nameof(ConfigGroupInstance)))?.Value; + AseUsername = (commandXml.Attribute(XName.Get(nameof(AseUsername)))?.Value) ?? "admin"; + AsePassword = (commandXml.Attribute(XName.Get(nameof(AsePassword)))?.Value) ?? "PASSWORD"; + Key = (commandXml.Attribute(XName.Get(nameof(Key)))?.Value) ?? ""; + Exe = (commandXml.Attribute(XName.Get(nameof(Exe)))?.Value)??"CURL\\curl.exe"; + ExeDir = Path.GetDirectoryName(Exe); + AseIp = commandXml.Attribute(XName.Get(nameof(AseIp)))?.Value; + ConfigFile = commandXml.Attribute(XName.Get(nameof(ConfigFile)))?.Value; + if (!Path.IsPathRooted(ConfigFile)) ConfigFile = Path.Combine(ExeDir, ConfigFile); + Description = (commandXml.Attribute(XName.Get(nameof(Description)))?.Value)??""; + Arguments = (commandXml.Attribute(XName.Get(nameof(Arguments)))?.Value)?? + ( + Type== CommandType.export? DEFAULTEXPORTARGUMENTS + : Type== CommandType.exportpartial ? DEFAULTEXPORTPARTIALARGUMENTS + : Type == CommandType.importnoanswer ? DEFAULTIMPORTNOANSWERARGUMENTS + : /*Type == CommandType.import ?*/DEFAULTIMPORTARGUMENTS + ); + ArgumentParameters = (commandXml.Attribute(XName.Get(nameof(ArgumentParameters)))?.Value)??""; + var plist = ArgumentParameters.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var p in plist) + { + var aname = p.Split('=')[0]; + string pvalue=""; try { pvalue = p.Split('=')[1]; } catch { } + var po = new ASEConfigCommandParameter(); + po.Name = aname; + if (pvalue.StartsWith("?")) { po.Interactive = true; po.Prompt = pvalue.Substring(1); } + else { po.Value = pvalue; } + ArgumentParameterList.Add(po); + } + } + public bool EqualsTo(string selection) + { + return Key.ToLower()==selection.ToLower(); + } + public List GetIpList() + { + return AseIpResolved.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); + } + public Tuple GetOneLineInfo(int keylength,int desclength) + { + if (keylength == 0) keylength = 6; + if (desclength == 0) desclength = 20; + string keystring = (Key + new string(' ', keylength)).Substring(0, keylength); + string descstring = (Description + new string(' ', desclength)).Substring(0, desclength); + return Tuple.Create(keystring, descstring, $"(Type={Type},CfgFile={ConfigFile},Ase:Ip={AseIp},UN={AseUsername},PSW={AsePassword})"); + } + public void Ini() + { + AseIpResolved = AseIp; + AseUsernameResolved=AseUsername; + AsePasswordResolved = AsePassword; + ConfigFileResolved = ConfigFile; + ArgumentsResolved = Arguments; + } + public bool SetArgumentParameters() + { + AseUsernameResolved = ASEConfigCommandParameter.SetCurrentValue(AseUsername, nameof(AseUsername)); + AsePasswordResolved = ASEConfigCommandParameter.SetCurrentValue(AsePassword, nameof(AsePassword)); + ConfigFileResolved = ASEConfigCommandParameter.SetCurrentValue(ConfigFile, nameof(ConfigFile)); + foreach (var p in ArgumentParameterList) { p.SetCurrentValue(); if (p.Value == null) return false; } + AseIpResolved = ASEConfigCommandParameter.SetCurrentValue(AseIp, nameof(AseIp)); + return true; + } + public bool DisplayArgumentParameters() + { + ColorConsole.WriteLine("Command parameters:"); + ColorConsole.WriteLine(AseIpResolved,prefix:$"{nameof(AseIp)}="); + ColorConsole.WriteLine(AseUsernameResolved, prefix: $"{nameof(AseUsername)}="); + ColorConsole.WriteLine(AsePasswordResolved, prefix: $"{nameof(AsePassword)}="); + ColorConsole.WriteLine(ConfigFileResolved, prefix: $"{nameof(ConfigFile)}="); + foreach (var p in ArgumentParameterList) { ColorConsole.WriteLine($"{p.Name}={p.Value}"); } + var answer = ColorConsole.ReadLine("Execute command with these parameters?", defaultvalue: "no", validitylist: new List() { "yes", "no", }, bracket: "[]"); + return answer.ToLower() == "yes"; + } + public bool Resolve(string currentip) + { + //resolve arguments + foreach (var a in ArgumentParameterList) + { + ArgumentsResolved = ArgumentsResolved.Replace($"{{{a.Name}}}", a.Value); + ConfigFileResolved = ConfigFileResolved.Replace($"{{{a.Name}}}", a.Value); + currentip = currentip.Replace($"{{{a.Name}}}", a.Value); + AseUsernameResolved = AseUsernameResolved.Replace($"{{{a.Name}}}", a.Value); + AsePasswordResolved = AsePasswordResolved.Replace($"{{{a.Name}}}", a.Value); + } + ConfigFileResolved = ConfigFileResolved.Replace($"{{{nameof(AseIp).ToUpper()}}}", currentip); + ArgumentsResolved = ArgumentsResolved.Replace($"{{{nameof(AseIp).ToUpper()}}}", currentip); + ArgumentsResolved = ArgumentsResolved.Replace($"{{{nameof(AseUsername).ToUpper()}}}", AseUsernameResolved); + ArgumentsResolved = ArgumentsResolved.Replace($"{{{nameof(AsePassword).ToUpper()}}}", AsePasswordResolved); + if (Type== CommandType.exportpartial) ArgumentsResolved = ArgumentsResolved.Replace($"{{{nameof(ConfigGroupName).ToUpper()}}}", ConfigGroupName); + if (Type == CommandType.exportpartial) ArgumentsResolved = ArgumentsResolved.Replace($"{{{nameof(ConfigGroupInstance).ToUpper()}}}", ConfigGroupInstance); + + //resolve config files + if (Type == CommandType.import || Type == CommandType.importnoanswer) + { + try + { + var cfgfilecontent = System.IO.File.ReadAllText(ConfigFileResolved); + foreach (var a in ArgumentParameterList) + { + cfgfilecontent = cfgfilecontent.Replace($"{{{a.Name}}}", a.Value); + } + cfgfilecontent = cfgfilecontent.Replace($"{{{nameof(AseIp).ToUpper()}}}", currentip); + cfgfilecontent = cfgfilecontent.Replace($"{{{nameof(ConfigFile).ToUpper()}}}", ConfigFileResolved); + var tempfilename = Path.GetTempFileName(); + System.IO.File.WriteAllText(tempfilename, cfgfilecontent); + ArgumentsResolved = ArgumentsResolved.Replace($"{{{nameof(ConfigFile).ToUpper()}}}", tempfilename); + return true; + } + catch (Exception ex) + { + ColorConsole.WriteLine(ex.Message, f: ConsoleColor.Red); + return false; + } + } + return true; + } + public void Execute() + { + Console.WriteLine($"Executing:{Exe} {ArgumentsResolved}"); + using (System.Diagnostics.Process pProcess = new System.Diagnostics.Process()) + { + Process ExternalProcess = new Process(); + ExternalProcess.StartInfo.FileName = Exe; + ExternalProcess.StartInfo.UseShellExecute = false; + ExternalProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + + ExternalProcess.StartInfo.RedirectStandardOutput = true; + ExternalProcess.OutputDataReceived += (sender, args) => Console.WriteLine("received output: {0}", args.Data); + + ExternalProcess.StartInfo.Arguments = ArgumentsResolved; + ExternalProcess.Start(); + ExternalProcess.BeginOutputReadLine(); + ExternalProcess.WaitForExit(-1); + } + } + public string Key; + private CommandType Type; + private string ConfigGroupName; + private string ConfigGroupInstance; + private string AseUsername; + private string AseUsernameResolved; + private string AsePassword; + private string AsePasswordResolved; + public string Description; + private string Exe; + private string ExeDir; + private string ConfigFile; + private string ConfigFileResolved; + private string AseIp; + private string AseIpResolved; + private string Arguments; + private string ArgumentsResolved; + private string ArgumentParameters; + private List ArgumentParameterList = new List(); + } + private class ASEConfigCommandParameter + { + public string Name; + public string Value=""; + public bool Interactive=false; + public string Prompt=""; + public string SetCurrentValue() { return SetCurrentValue(Interactive,Value,Prompt,Name); } + public static string SetCurrentValue(string valueorinteractive, string name) + { + string prompt = null; + string value = null; + bool interactive = valueorinteractive.StartsWith("?"); + if (interactive) { prompt = valueorinteractive == "?" ? "" : valueorinteractive.Substring(1); } else { value = valueorinteractive; } + return SetCurrentValue(interactive,value,prompt,name); + } + private static string SetCurrentValue(bool interactive, string value,string prompt, string name) + { + if (!interactive) return value; + string prompttext = string.IsNullOrWhiteSpace(prompt) ? $"Enter {name}" : $"{prompt} ({name})"; + ColorConsole.WriteLine(prompttext,ConsoleColor.Yellow); + ColorConsole.WriteLine($"Enter NONE (or nothing) for no value!", ConsoleColor.Gray); + value = ColorConsole.ReadLine(); + value = value.ToLower() == "ex" ? null + : value.ToLower() == "none" ? "<None>" + : value == "" ? "<None>" + : value; + return value; + } + } + #endregion ASEConfig + #region Tool templates - private static object Tool2(object parameter, object o) + private static object Tool(object parameter, object o) { var config = (parameter as Menu.ExecutorParameter).GetConfig(); - var regexptesterconfig = config.RegexpTesterConfig; - ColorConsole.ReadLine($"{nameof(Tool2)} is not ready yet...", ConsoleColor.Yellow); + var regexptesterconfig = config.ToolConfigXml; + ColorConsole.ReadLine($"{nameof(Tool)} is not ready yet...", ConsoleColor.Yellow); return o; } #endregion Tool templates @@ -406,8 +650,10 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS public bool WaitForExit=XmlStructure.ExternalUtility.Attributes.WaitForExit.Values.DEFAULT; public bool Valid; } - public XElement RegexpTesterConfig; + public XElement RegexpTesterConfigXml; public XElement PingerConfigXml; + public XElement ASEConfigXml; + public XElement ToolConfigXml; public class IPAddressParsingResult { public IPAddress IP; @@ -421,7 +667,9 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS #region constructor public MaintenanceToolsXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) { - RegexpTesterConfig = GetXElement(nameof(XmlStructure.RegexpTester)); + RegexpTesterConfigXml = GetXElement(nameof(XmlStructure.RegexpTester)); + ASEConfigXml = GetXElement(nameof(XmlStructure.ASEConfig)); + ToolConfigXml = GetXElement(nameof(XmlStructure.ToolConfig)); var TcpIpTesterXml = GetXElement(nameof(XmlStructure.TcpIpTester)); if (TcpIpTesterXml != null) @@ -451,6 +699,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS public static class XmlStructure { public static class RegexpTester { } + public static class ASEConfig { } + public static class ToolConfig { } public static class ExternalUtility { public static class Attributes diff --git a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs index bcf9ecf..c227e7e 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.18.1.0")] -[assembly: AssemblyFileVersion("1.18.1.0")] +[assembly: AssemblyVersion("1.19.0.0")] +[assembly: AssemblyFileVersion("1.19.0.0")] -- libgit2 0.21.2