public HandlerResult ExecuteHandlerProcess_SingleAction(ActionItem a, Dictionary <string, string> dynamicData, bool dryRun = false)
        {
            HandlerResult returnResult = HandlerResult.Emtpy;

            string parms = ResolveConfigAndParameters(a, dynamicData);

            IHandlerRuntime rt = CreateHandlerRuntime(a.Name, a.Handler);

            rt.Progress += rt_Progress;

            if (!WantsStopOrPause())
            {
                a.RunAs?.Impersonate();
                HandlerResult r = rt.Execute(parms, dryRun);
                a.RunAs?.Undo();

                if (r.Status > returnResult.Status)
                {
                    returnResult = r;
                }
            }

            return(returnResult);
        }
예제 #2
0
        void WriteUnhandledActionException(ActionItem a, Exception ex, bool writeProgress = true, bool writeLog = true)
        {
            //todo: serialize exception to composite string
            string context = "Synapse.Core PlanRuntime";
            string message = $"An unhandled exeption occurred in {a.Name}, Plan/Action Instance: {InstanceId}/{a.InstanceId}. Message: {ex.Message}.";

            if (writeProgress)
            {
                HandlerProgressCancelEventArgs e =
                    new HandlerProgressCancelEventArgs(context: context, message: message, status: StatusType.Failed,
                                                       id: a.InstanceId, sequence: Int32.MaxValue - 100, cancel: false, ex: ex)
                {
                    ActionName = a.Name
                };
                rt_Progress(this, e);
            }

            if (writeLog)
            {
                LogMessageEventArgs e =
                    new LogMessageEventArgs(context: context, message: message, level: LogLevel.Fatal, ex: ex);
                rt_LogMessage(this, e);
            }
        }
예제 #3
0
        //note: this doesn't implement SaveExitDataAs( action );
        private ExecuteResult SpawnExternal(ActionItem a, Dictionary <string, string> dynamicData, object parentExitData, bool dryRun)
        {
            ExecuteResult result = new ExecuteResult();
            List <string> args   = new List <string>();

            Plan container = new Plan();

            a.InstanceId   = ActionInstanceIdCounter++;
            container.Name = $"{Name}:{a.Name}";
            container.Actions.Add(a.Clone());
            container.StartInfo = StartInfo;

            string planYaml = CryptoHelpers.Encode(container.ToYaml());

            args.Add($"/plan:{planYaml}");
            args.Add($"/dryRun:{dryRun}");
            args.Add($"/taskModel:single");
            foreach (string key in dynamicData.Keys)
            {
                args.Add($"/{key}:{dynamicData[key]}");
            }
            args.Add($"/data:{parentExitData}");
            string arguments = string.Join(" ", args);

            Process p = new Process();

            p.StartInfo.Arguments              = arguments;
            p.StartInfo.FileName               = "synapse.cli.exe";
            p.StartInfo.RedirectStandardInput  = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError  = true;
            p.StartInfo.UseShellExecute        = false;
            p.StartInfo.CreateNoWindow         = true;
            p.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
            p.EnableRaisingEvents              = true;
            //if( a.HasRunAs )
            //{
            //    p.StartInfo.Domain = a.RunAs.Domain;
            //    p.StartInfo.UserName = a.RunAs.UserName;
            //    SecureString pw = new SecureString();
            //    foreach( char c in a.RunAs.Password )
            //        pw.AppendChar( c );
            //    p.StartInfo.Password = pw;
            //}

            p.OutputDataReceived += p_OutputDataReceived;

            p.Start();

            result.PId = p.Id;
#if sqlite
            a.UpdateInstanceStatus(StatusType.None, "SpawnExternal", 0, p.Id);
#endif
            #region read this
            // best practice information on accessing stdout/stderr from mdsn article:
            //  https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput%28v=vs.110%29.aspx
            // Do not wait for the child process to exit before reading to the end of its redirected stream.
            // Do not perform a synchronous read to the end of both redirected streams.
            // string output = p.StandardOutput.ReadToEnd();
            // string error = p.StandardError.ReadToEnd();
            // p.WaitForExit();
            // Use asynchronous read operations on at least one of the streams.
            #endregion
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();


            p.WaitForExit();

            result.BranchStatus = result.Status = (StatusType)p.ExitCode;
            return(result);
        }
예제 #4
0
 ExecuteResult ExecuteHandlerProcessExternal(SecurityContext parentSecurityContext, ActionItem a,
                                             Dictionary <string, string> dynamicData, object parentExitData, bool dryRun = false)
 {
     if (!WantsStopOrPause())
     {
         try
         {
             //if( !a.HasRunAs ) a.RunAs = parentSecurityContext;
             a.IngestParentSecurityContext(parentSecurityContext);
             a.Result = SpawnExternal(a, dynamicData, parentExitData, dryRun);
             return(a.Result);
         }
         catch (Exception ex)
         {
             WriteUnhandledActionException(a, ex);
             return(new ExecuteResult()
             {
                 Status = StatusType.Failed
             });
         }
     }
     else
     {
         return(new ExecuteResult());
     }
 }
예제 #5
0
        ExecuteResult ExecuteHandlerProcessInProc(SecurityContext parentSecurityContext, ActionItem a,
                                                  Dictionary <string, string> dynamicData, object parentExitData, bool dryRun = false)
        {
            try
            {
                //string parms = ResolveConfigAndParameters( a, dynamicData );
                string parms = a.Parameters.GetSerializedValues(Crypto);

                IHandlerRuntime rt = CreateHandlerRuntime(a);
                rt.Progress   += rt_Progress;
                rt.LogMessage += rt_LogMessage;

                if (!WantsStopOrPause())
                {
                    a.IngestParentSecurityContext(parentSecurityContext);
                    SecurityContext sc = a.RunAs; //just an alias
                    sc?.Crypto?.InheritSettingsIfRequired(Crypto);

                    HandlerStartInfo startInfo = new HandlerStartInfo(StartInfo)
                    {
                        Parameters     = parms,
                        IsDryRun       = dryRun,
                        PlanInstanceId = InstanceId,
                        InstanceId     = a.InstanceId,
                        ParentExitData = parentExitData,
                        RunAs          = sc,
                        Crypto         = a.Parameters?.Crypto
                    };
                    a.Handler.StartInfo = new HandlerStartInfoData(startInfo);

                    sc?.Impersonate(Crypto);

                    a.Result = rt.Execute(startInfo);
                    a.Result.BranchStatus    = a.Result.Status;
                    a.Result.SecurityContext = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

                    SaveExitDataAs(a);

                    sc?.Undo();
                }

                return(a.Result);
            }
            catch (Exception ex)
            {
                WriteUnhandledActionException(a, ex);
                return(new ExecuteResult()
                {
                    Status = StatusType.Failed, ExitData = ex.Message
                });
            }
        }
예제 #6
0
        void ProcessRecursive(IActionContainer parentContext, SecurityContext parentSecurityContext,
                              ActionItem actionGroup, List <ActionItem> actions, ExecuteResult parentResult,
                              Dictionary <string, string> dynamicData, bool dryRun,
                              Func <SecurityContext, ActionItem, Dictionary <string, string>, object, bool, ExecuteResult> executeHandlerMethod)
        {
            if (WantsStopOrPause())
            {
                return;
            }


            parentContext.EnsureInitialized();

            //queryStatus provides the inbound value to ExecuteCase evaluation; it's the ExecuteCase comparison value.
            //queryStatus is carried downward through successive subtree executions.
            StatusType queryStatus = parentResult.Status;

            #region actionGroup
            if (actionGroup != null &&
                (((actionGroup.ExecuteCase & parentResult.Status) == actionGroup.ExecuteCase) || (actionGroup.ExecuteCase == StatusType.Any)))
            {
                actionGroup.EnsureInitialized();

                #region actionGroup-forEach
                if ((actionGroup.HasParameters && actionGroup.Parameters.HasForEach) ||
                    (actionGroup.Handler.HasConfig && actionGroup.Handler.Config.HasForEach))
                {
                    List <ActionItem> resolvedParmsActionGroup = new List <ActionItem>();
                    ResolveConfigAndParameters(actionGroup, dynamicData, ref resolvedParmsActionGroup, parentResult.ExitData);

                    foreach (ActionItem ai in resolvedParmsActionGroup)
                    {
                        ai.Parameters.ForEach = null;
                    }

                    actionGroup.InstanceId = ActionInstanceIdCounter++;
                    ActionItem agclone = actionGroup.Clone();
                    agclone.Result            = new ExecuteResult();
                    parentContext.ActionGroup = agclone;

                    Parallel.ForEach(resolvedParmsActionGroup, a =>    // foreach( ActionItem a in resolvedParmsActionGroup )
                    {
#if sqlite
                        a.CreateInstance(parentContext, InstanceId);
#endif
                        a.InstanceId     = ActionInstanceIdCounter++;
                        ActionItem clone = a.Clone();
                        agclone.Actions.Add(clone);

                        ExecuteResult r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun);
                        parentContext.ActionGroup.Result.SetBranchStatusChecked(r);
                        parentContext.Result.SetBranchStatusChecked(r);
                        clone.Handler.Type      = actionGroup.Handler.Type;
                        clone.Handler.StartInfo = actionGroup.Handler.StartInfo;
                        clone.Result            = r;

                        if (r.Status > queryStatus)
                        {
                            queryStatus = r.Status;
                        }

                        if (a.HasActions)
                        {
                            ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                            parentContext.ActionGroup.Result.SetBranchStatusChecked(clone.Result);
                            parentContext.Result.SetBranchStatusChecked(clone.Result);

                            if (clone.Result.Status > queryStatus)
                            {
                                queryStatus = clone.Result.Status;
                            }
                        }
                    });
                }
                #endregion
                #region actionGroup-single
                else
                {
#if sqlite
                    actionGroup.CreateInstance(parentContext, InstanceId);
#endif
                    ResolveConfigAndParameters(actionGroup, dynamicData, parentResult.ExitData);

                    actionGroup.InstanceId = ActionInstanceIdCounter++;
                    ActionItem clone = actionGroup.Clone();
                    parentContext.ActionGroup = clone;

                    ExecuteResult r = executeHandlerMethod(parentSecurityContext, actionGroup, dynamicData, parentResult.ExitData, dryRun);
                    parentContext.Result.SetBranchStatusChecked(r);
                    clone.Handler.Type      = actionGroup.Handler.Type;
                    clone.Handler.StartInfo = actionGroup.Handler.StartInfo;
                    clone.Result            = r;

                    if (r.Status > queryStatus)
                    {
                        queryStatus = r.Status;
                    }

                    if (actionGroup.HasActions)
                    {
                        ProcessRecursive(clone, actionGroup.RunAs, null, actionGroup.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                        parentContext.Result.SetBranchStatusChecked(clone.Result);

                        if (clone.Result.Status > queryStatus)
                        {
                            queryStatus = clone.Result.Status;
                        }
                    }
                }
                #endregion
            }
            #endregion


            #region actions
            IEnumerable <ActionItem> actionList =
                actions.Where(a => (((a.ExecuteCase & queryStatus) == a.ExecuteCase) || (a.ExecuteCase == StatusType.Any)));

            List <ActionItem> resolvedParmsActions = new List <ActionItem>();
            Parallel.ForEach(actionList, a =>    // foreach( ActionItem a in actionList )
                             ResolveConfigAndParameters(a, dynamicData, ref resolvedParmsActions, parentResult.ExitData)
                             );

            Parallel.ForEach(resolvedParmsActions, a =>    // foreach( ActionItem a in resolvedParmsActions )
            {
#if sqlite
                a.CreateInstance(parentContext, InstanceId);
#endif
                a.InstanceId     = ActionInstanceIdCounter++;
                ActionItem clone = a.Clone();
                parentContext.Actions.Add(clone);

                ExecuteResult r = a.Result;
                if (r?.Status != StatusType.Failed)
                {
                    r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun);
                }

                parentContext.Result.SetBranchStatusChecked(r);
                clone.Handler.Type      = a.Handler.Type;
                clone.Handler.StartInfo = a.Handler.StartInfo;
                clone.Result            = r;

                if (a.HasActions)
                {
                    ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                    parentContext.Result.SetBranchStatusChecked(clone.Result);
                }
            });
            #endregion
        }
예제 #7
0
        public void ResolveConfigAndParameters(Dictionary <string, string> dynamicData,
                                               Dictionary <string, ParameterInfo> globalConfigSets, Dictionary <string, ParameterInfo> globalParamSets, ref List <ActionItem> resolvedActions, object parentExitData)
        {
            if (Handler == null)
            {
                Handler = new HandlerInfo();
            }

            List <object> forEachConfigs = new List <object>();

            if (Handler.HasConfig)
            {
                ParameterInfo c = Handler.Config;
                if (globalConfigSets != null && c.HasInheritFrom && globalConfigSets.Keys.Contains(c.InheritFrom))
                {
                    c.InheritedValues = globalConfigSets[c.InheritFrom];
                }

                c.Resolve(out forEachConfigs, dynamicData, parentExitData, globalConfigSets);

                if (globalConfigSets != null && c.HasName)
                {
                    globalConfigSets[c.Name] = c;
                }
            }
            else
            {
                Handler.Config = new ParameterInfo()
                {
                };
                forEachConfigs.Add(null);
            }

            List <object> forEachParms = new List <object>();

            if (HasParameters)
            {
                ParameterInfo p = Parameters;
                if (globalParamSets != null && p.HasInheritFrom && globalParamSets.Keys.Contains(p.InheritFrom))
                {
                    p.InheritedValues = globalParamSets[p.InheritFrom];
                }

                p.Resolve(out forEachParms, dynamicData, parentExitData, globalParamSets);

                if (globalParamSets != null && p.HasName)
                {
                    globalParamSets[p.Name] = p;
                }
            }
            else
            {
                Parameters = new ParameterInfo()
                {
                };
                forEachParms.Add(null);
            }

            if (resolvedActions != null)
            {
                foreach (object forEachConfig in forEachConfigs)
                {
                    foreach (object forEachParm in forEachParms)
                    {
                        ActionItem clone = Clone(shallow: false);
                        clone.Handler.Config.Values = forEachConfig;
                        clone.Parameters.Values     = forEachParm;

                        resolvedActions.Add(clone);
                    }
                }
            }
        }
        HandlerResult ExecuteHandlerProcessExternal(SecurityContext parentSecurityContext, ActionItem a, Dictionary <string, string> dynamicData, bool dryRun = false)
        {
            HandlerResult returnResult = HandlerResult.Emtpy;

            if (!WantsStopOrPause())
            {
                if (!a.HasRunAs)
                {
                    a.RunAs = parentSecurityContext;
                }
                HandlerResult r = SpawnExternal(a, dynamicData, dryRun);

                if (r.Status > returnResult.Status)
                {
                    returnResult = r;
                }
            }

            return(returnResult);
        }
        HandlerResult ProcessRecursiveExternal(SecurityContext parentSecurityContext, ActionItem actionGroup, List <ActionItem> actions, HandlerResult result,
                                               Dictionary <string, string> dynamicData, bool dryRun = false)
        {
            if (WantsStopOrPause())
            {
                return(result);
            }

            HandlerResult returnResult = HandlerResult.Emtpy;

            StatusType queryStatus = result.Status;

            if (actionGroup != null && actionGroup.ExecuteCase == result.Status)
            {
                HandlerResult r = ExecuteHandlerProcessExternal(parentSecurityContext, actionGroup, dynamicData, dryRun);
                if (r.Status > returnResult.Status)
                {
                    returnResult = r;
                }

                if (actionGroup.HasActions)
                {
                    r = ProcessRecursiveExternal(parentSecurityContext, null, actionGroup.Actions, r, dynamicData, dryRun);
                }
                if (r.Status > returnResult.Status)
                {
                    returnResult = r;
                }

                if (r.Status > queryStatus)
                {
                    queryStatus = r.Status;
                }
            }

            IEnumerable <ActionItem> actionList = actions.Where(a => a.ExecuteCase == queryStatus);

            Parallel.ForEach(actionList, a =>
            {
                HandlerResult r = ExecuteHandlerProcessExternal(parentSecurityContext, a, dynamicData, dryRun);
                if (a.HasActions)
                {
                    r = ProcessRecursiveExternal(a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun);
                }

                if (r.Status > returnResult.Status)
                {
                    returnResult = r;
                }
            });

            return(returnResult);
        }