/// <summary> /// schedule a plugin to be executed at each heartbeat /// </summary> /// <param name="plugin">the plugin to be scheduled</param> public override void SchedulePlugin(APlugin plugin) { if (!plugin.CanBeRun()) { return; } try { // the scheduler is called to run the plugin each heartbeat SchedulerService.Instance.ScheduleTask($"task_{plugin.Infos.FileName}", plugin.Heartbeat, () => { try { Run(plugin); Log.Instance?.Info($"{plugin.Infos.FileName} correctly executed."); } catch (Exception e) { Log.Instance?.Error($"{plugin.Infos.FileName} had a problem: {e.Message}"); } }); } catch (Exception e) { Log.Instance?.Error($"SchedulePlugin: {e.Message}"); } }
/// <summary> /// run a code from a shared object fille /// </summary> /// <param name="plugin">plugin to be executed</param> public void RunFromSO(APlugin plugin) { // .so works only on linux if (OSAttribute.IsLinux) { QueueLength++; ThreadPool.QueueUserWorkItem(obj => { try { using var dllimport = new DllImportEntryPoint(); var result = dllimport.UseRunEntryPointSharedObject(plugin.Infos.FilePath); plugin.RaiseOnExecutionFinished(result); } catch (Exception e) { Log.Instance?.Error($"{plugin.Infos.FileName} encountered a problem: {e.Message}"); } finally { Consume(); } }); } }
private void ExecuteScriptLinux(APlugin plugin, string file, string args) { using var dllimport = new DllImportLaunchCmdUnix(); var result = ""; if (plugin.AdministratorRights) { result = dllimport.UseLaunchCommand( $"sudo -u {plugin.AdministratorUsername} -s {file} -c {args} 2> /dev/null"); } else { result = dllimport.UseLaunchCommand($"{file} {args} 2> /dev/null"); } // if it's not a valid json try { JObject.Parse(result); } catch (JsonReaderException) { Log.Instance?.Error($"{plugin.Infos.Name}: result not in a json format: {result}"); return; } plugin.RaiseOnExecutionFinished(result); }
private static void PrintPluginLine(APlugin plugin, bool valid, string error) { Console.ForegroundColor = valid ? ConsoleColor.Green : ConsoleColor.Red; Console.Write($"[{plugin.Infos.FileName}]:"); Console.ResetColor(); Console.WriteLine($" {error}"); }
/// <summary> /// run a code from a dll (dotnet dll and classical dll) /// </summary> /// <param name="plugin">plugin to be executed</param> public void RunFromDLL(APlugin plugin) { QueueLength++; ThreadPool.QueueUserWorkItem(obj => { // TODO: verifier si il y a un moyen de connaitre si c est une dll dotnet try { TryRunAssemblyDLL(plugin); } catch (Exception e) { // if it can't load assembly, it need to try a classic type file dll if (e is BadImageFormatException) { RunClassicDLL(plugin); } } finally { Consume(); } }); }
private void RunClassicDLL(APlugin plugin) { using var dllimport = new DllImportEntryPoint(); var result = dllimport.UseRunEntryPointSharedObject(plugin.Infos.FilePath); plugin.RaiseOnExecutionFinished(result); }
public async Task <StorageCode> Save <T>(APlugin plugin, T obj) { if (!HasDifference(plugin, obj)) { return(StorageCode.Pass); } return(await SaveDifferencial(plugin, obj)); }
public void AddPlugin(APlugin aPlugin) { aPlugin.Servers = Servers; aPlugin.Files = Files; aPlugin.Searches = Searches; aPlugin.Notifications = Notifications; aPlugin.ApiKeys = ApiKeys; aPlugin.Scheduler = Scheduler; _plugins.Add(aPlugin); }
private void StartProcess(APlugin plugin, string file, string args) { if (OSAttribute.IsLinux) { ExecuteScriptLinux(plugin, file, args); } else if (OSAttribute.IsWindows) { ExecuteScriptWindows(plugin, file, args); } }
public bool HasDifference <T>(APlugin plugin, T obj) { if (!plugin.ObserveAllAttributes && plugin.AttributesToObserve == null) { return(true); } var key = plugin.Infos.Name; var convertedJsonObject = JObject.Parse(obj.ToString()); if (!storedObject.ContainsKey(plugin.Infos.Name)) { storedObject.Add(key, convertedJsonObject); return(true); } List <string> attributesToObserve; if (plugin.ObserveAllAttributes) { attributesToObserve = new List <string>(); foreach (var token in convertedJsonObject) { attributesToObserve.Add(token.Key); } } else { attributesToObserve = plugin.AttributesToObserve; } foreach (var attr in attributesToObserve) { var storedAttr = storedObject[key][attr]; if (convertedJsonObject[attr] == null) { Log.Instance?.Warn( $"Attribute {attr} in differencial mode on plugin '{plugin.Infos.FileName}' is uknown. Difference returned is true."); return(true); } if (!comparer.Equals(convertedJsonObject[attr], storedAttr)) { storedObject[key] = convertedJsonObject; return(true); } } return(false); }
public override async Task <StorageCode> SaveDifferencial <T>(APlugin plugin, T obj) { var strTodayDate = DateTime.Now.ToString("yyyy-MM-dd"); var completeTodayDate = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss.ff"); var path = $"{strTodayDate}/{Environment.MachineName}/{plugin.Infos.Name}"; var fileName = $"{completeTodayDate}_{plugin.Infos.Name}.json"; await StreamWriter.WriteLineAsync($"{path};{fileName};{obj.ToString()}"); await StreamWriter.FlushAsync(); return(StorageCode.Success); }
public async Task <StorageCode> Save <T>(APlugin plugin, T obj) { var dirName = "results/"; var strTodayDate = DateTime.Now.ToString("yyyy-MM-dd"); var completeTodayDate = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); var folder = $"{SavePath}/{dirName}{strTodayDate}/{plugin.Infos.Name}/"; Directory.CreateDirectory(folder); using var fw = File.CreateText($"{folder}{completeTodayDate}_{plugin.Infos.Name}.json"); await fw.WriteAsync(obj.ToString()); return(StorageCode.Success); }
private void TryRunAssemblyDLL(APlugin plugin) { var assembly = Assembly.LoadFrom(plugin.Infos.FilePath); var type = assembly.GetTypes().FirstOrDefault(); var entryPointMethod = type?.GetMethod(MethodEntryPointName); if (entryPointMethod != null) { dynamic instance = Activator.CreateInstance(type); var result = entryPointMethod.Invoke(instance, null); plugin.RaiseOnExecutionFinished(result); } else { Log.Instance?.Error($"Method '{MethodEntryPointName}' from DLL {plugin.Infos.FileName} not found."); } }
/// <summary> /// run a code from a script language /// </summary> /// <param name="plugin">plugin to be executed</param> public void RunFromScript(APlugin plugin) { QueueLength++; ThreadPool.QueueUserWorkItem(obj => { var file = ""; var args = plugin.Infos.FilePath; var fileExtension = plugin.Infos.FileExtension; // check if the extension is known if (!refPluginMaster.ExtensionsNames.ContainsKey(plugin.Infos.FileExtension)) { Log.Instance?.Error("Unknown extension."); } file = refPluginMaster.ExtensionsNames[fileExtension]; // check if the extension had been set if (string.IsNullOrEmpty(file)) { Log.Instance?.Error( $"Value {refPluginMaster.ExtensionsNames[fileExtension]} from interpreter object in json file not found."); return; } try { StartProcess(plugin, file, args); } catch (Exception e) { Log.Instance?.Error($"{plugin.Infos.FileName} encountered a problem: {e.Message}"); } finally { Consume(); } }); }
public override async Task <StorageCode> SaveDifferencial <T>(APlugin plugin, T obj) { var anonymousObject = JObject.Parse(obj.ToString()); var collection = defaultDatabase.GetCollection <dynamic>("results"); dynamic document = new ExpandoObject(); document.date = DateTime.UtcNow.ToString("s"); document.name = plugin.Infos.Name; document.machine_name = Environment.MachineName; document.result = BsonSerializer.Deserialize <dynamic>(obj.ToString()); await collection.InsertOneAsync(document, new InsertOneOptions { BypassDocumentValidation = true }); return(StorageCode.Success); }
/// <summary> /// run a plugin depending it's type /// </summary> /// <param name="plugin">plugin to be executed</param> public void Run(APlugin plugin) { if (!plugin.CanBeRun()) { return; } switch (plugin.Type) { case PluginFileInfos.FileType.DLL: Executor.RunFromDLL(plugin); break; case PluginFileInfos.FileType.Script: Executor.RunFromScript(plugin); break; case PluginFileInfos.FileType.SharedObject: Executor.RunFromSO(plugin); break; } }
public async Task <StorageCode> Save <T>(APlugin plugin, T obj) { var resultProtocol = new LineProtocolPoint( plugin.Infos.Name, new Dictionary <string, object> { { "result", JsonConvert.DeserializeObject <dynamic>(obj.ToString()) } } ); var payload = new LineProtocolPayload(); payload.Add(resultProtocol); var influxResult = await client.WriteAsync(payload); if (influxResult.Success) { return(StorageCode.Success); } return(StorageCode.Failed); }
private void ExecuteScriptWindows(APlugin plugin, string file, string args) { var verb = ""; var username = ""; // if the plugin is a powershell scripts, it needs some tweeks to execute it if (plugin.Infos.FileExtension.Equals(".ps1")) { file = "Powershell.exe"; args = $"-executionpolicy remotesigned -File {args}"; } var start = new ProcessStartInfo { FileName = file, Arguments = args, Verb = verb, UserName = username, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; using var process = Process.Start(start); using var readerOutput = process.StandardOutput; using var readerInput = process.StandardError; var err = readerInput.ReadToEnd(); if (!string.IsNullOrEmpty(err)) { Log.Instance?.Error($"Plugin encoutered an error: {err}"); throw new ApplicationException(err); } plugin.RaiseOnExecutionFinished(readerOutput.ReadToEnd()); }
/// <summary> /// set a plugin's configuration from the configuration file /// </summary> /// <param name="plugin"></param> public abstract void SetPluginConfiguration(APlugin plugin);
public abstract Task <StorageCode> SaveDifferencial <T>(APlugin plugin, T obj);
/* * A plugin's configuration is composed of 3 majors attributes: * - hearthbeat (in hours), the plugin will be launched one time per heartbeat. * - activated (bool), tell if the plugin is activated or not * - os (array), is composed of one or more familly os (linux, windows, osx) * plugin will be executed only on the specified OS * */ public override void SetPluginConfiguration(APlugin plugin) { if (Root == null) { return; } var pluginConfig = Root[MagicStringEnumerator.JSONPlugins].Value <JObject>(plugin.Infos.FileName); T _SetAttribute <T>(string name, T fallback) where T : struct { var val = pluginConfig[name]?.Value <T?>(); if (val == null) { Log.Instance?.Warn( $"{plugin.Infos.FileName} has not \"{name}\" set. Default value used \"{fallback}\"."); return(fallback); } return(val.Value); } // plugin needs to have a specific configuration, otherwise it can't be run if (pluginConfig == null) { throw new NullReferenceException($"Plugin {plugin.Infos.FileName} does not have any configuration."); } plugin.Heartbeat = _SetAttribute(MagicStringEnumerator.JSONHeartbeat, 1.0f); plugin.Activated = _SetAttribute(MagicStringEnumerator.JSONActivated, false); if (OSAttribute.IsLinux) { var needAdministratorRights = _SetAttribute(MagicStringEnumerator.JSONAdminRights, false); if (needAdministratorRights) { var administratorUsername = pluginConfig[MagicStringEnumerator.JSONAdminUsername]?.Value <string>(); if (string.IsNullOrEmpty(administratorUsername)) { throw new ArgumentException( $"Adminstrator username must be specified in {plugin.Infos.FileName}'."); } plugin.AdministratorUsername = administratorUsername; } } // if no os is specified then all of them are authorized if (pluginConfig[MagicStringEnumerator.JSONOs] == null) { plugin.OsAuthorized |= OSAttribute.TargetFlag.All; } else { foreach (var os in pluginConfig[MagicStringEnumerator.JSONOs].ToObject <string[]>()) { if (!OSAttribute.OSNameToTargetFlag.ContainsKey(os)) { throw new ArgumentException($"OS {os} is not recognized."); } plugin.OsAuthorized |= OSAttribute.OSNameToTargetFlag[os]; } } if (pluginConfig[MagicStringEnumerator.JSONDifferencialAll]?.Value <bool>() == true) { plugin.ObserveAllAttributes = true; } else { var attributesToObserve = GetAttributesToObserve(pluginConfig); if (attributesToObserve != null) { plugin.AttributesToObserve = attributesToObserve; } } }
public override async Task <StorageCode> SaveDifferencial <T>(APlugin plugin, T obj) { await Task.Run(() => { Console.WriteLine(obj); }); return(StorageCode.Success); }
public void Add(APlugin aPlugin) { _plugins.Add(aPlugin); }
public virtual void SchedulePlugin(APlugin plugin) { }