Beispiel #1
0
        protected override object CreateModel(ActionStatement action)
        {
            if (action.PositionalArguments?.Count != 1)
            {
                return(null);
            }

            var scriptName = LooselyQualifiedName.Parse(action.PositionalArguments[0]);

            var info = PowerShellScriptInfo.TryLoadAsync(scriptName).GetAwaiter().GetResult();

            if (info == null)
            {
                return(null);
            }

            return(new PSCallOperationModel
            {
                ScriptName = scriptName.ToString(),
                Arguments = info.Parameters.Select(p => new Argument
                {
                    DefaultValue = p.DefaultValue,
                    Description = p.Description,
                    IsBooleanOrSwitch = p.IsBooleanOrSwitch,
                    IsOutput = p.IsOutput,
                    Name = p.Name,
                    Value = p.IsOutput ? action.OutArguments.GetValueOrDefault(p.Name)?.ToString() : action.Arguments.GetValueOrDefault(p.Name)
                })
            });
        }
Beispiel #2
0
        public static async Task SetPropertiesAsync(object target, ActionStatement action, IVariableFunctionContext bmContext, IExecuterContext executerContext)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            var variableContext = new RompVariableEvaluationContext(bmContext, executerContext);
            await core.SetPropertiesAsync(target, action, variableContext, null);

            (target as IHasCredentials)?.SetValues();
            (core.GetTemplate(target) as IHasCredentials)?.SetValues();
        }
Beispiel #3
0
 private static ExtendedRichDescription GetStatementDescription(ActionStatement statement)
 {
     try
     {
         var operationType = ExtensionsManager.TryGetOperation(statement.ActionName.Namespace, statement.ActionName.Name);
         return(Operation.GetDescription(operationType, statement));
     }
     catch
     {
         return(new ExtendedRichDescription(
                    new RichDescription(statement.ActionName.ToString())
                    ));
     }
 }
 public bool PlayState(string StateName,Action onEnd=null, bool immdiately=false)
 {
     if (Debug)
     {
         StateDebug(StateName);
     }
    ActionStatement state= Statements.Find(e => e.name == StateName);
     if(state==null)return false;
     if (PackPlayer.SetCurrent(state.actions, onEnd, immdiately))
     {
         PackPlayer.Restart();
         return true;
     }
     return false;
 }
Beispiel #5
0
        public override ISimpleControl CreateView(ActionStatement action)
        {
            if (action.PositionalArguments?.Count != 1)
            {
                return(new LiteralHtml("Cannot edit this statement; the target script name is not present."));
            }

            var scriptName = LooselyQualifiedName.Parse(action.PositionalArguments[0]);
            var info       = PowerShellScriptInfo.TryLoadAsync(scriptName).GetAwaiter().GetResult();

            if (info == null)
            {
                return(new LiteralHtml("Cannot edit this statement; script metatdata could not be parsed."));
            }

            var argumentName = new KoElement(KoBind.text(nameof(Argument.Name)));
            var argumentDesc = new KoElement(
                KoBind.text(nameof(Argument.Description))
                );

            var field = new SlimFormField(new LiteralHtml(argumentName.ToString()));

            field.HelpText = new LiteralHtml(argumentDesc.ToString());
            field.Controls.Add(
                new Element("input",
                            new KoBindAttribute("planargvalue", nameof(Argument.Value)))
            {
                Attributes = { ["type"] = "text" }
            });

            return(new SimpleVirtualCompositeControl(
                       new SlimFormField("Script name:", info.Name ?? scriptName.ToString()),
                       new Div(
                           new KoElement(
                               KoBind.@foreach(nameof(PSCallOperationModel.Arguments)),
                               field
                               )
                           )
            {
                Class = "argument-container"
            },
                       new SlimFormField(
                           "Parameters:",
                           KoBind.visible($"{nameof(PSCallOperationModel.Arguments)}().length == 0"),
                           "This script does not have any input or output parameters."
                           )
                       ));
        }
Beispiel #6
0
        private static void Validate(ActionStatement statement, ValidateStatementEventArgs e)
        {
            Type operationType;

            try
            {
                operationType = ExtensionsManager.TryGetOperation(statement.ActionName.Namespace, statement.ActionName.Name);
                if (operationType == null)
                {
                    e.AddError($"Unknown operation \"{statement.ActionName.FullName}\".");
                    return;
                }
            }
            catch (Exception ex)
            {
                e.AddError($"Unknowable operation \"{statement.ActionName.FullName}\": {ex.Message}.");
                return;
            }

            var defaultPropertyName = operationType.GetCustomAttribute <DefaultPropertyAttribute>()?.Name;

            var properties = from p in operationType.GetProperties()
                             where Attribute.IsDefined(p, typeof(RequiredAttribute)) && !Attribute.IsDefined(p, typeof(DefaultValueAttribute))
                             let aliases = p.GetCustomAttributes <ScriptAliasAttribute>().Select(a => a.Alias).ToList()
                                           where aliases.Count > 0
                                           select new
            {
                Property = p,
                Aliases  = aliases
            };

            foreach (var p in properties)
            {
                if (!p.Aliases.Any(a => statement.Arguments.ContainsKey(a)))
                {
                    if (p.Property.Name != defaultPropertyName || statement.PositionalArguments.Count == 0)
                    {
                        e.AddError($"Missing required \"{p.Aliases[0]}\" argument for \"{statement.ActionName.FullName}\" operation.");
                    }
                }
            }
        }
Beispiel #7
0
        public async Task <ActionExecutionResult> ExecuteActionAsync(ActionStatement actionStatement, IExecuterContext context)
        {
            var metric = new OtterScriptOperationEventMetric(actionStatement.ActionName.FullName);

            try
            {
                var rompContext = ((RompExecutionContext)context.ExternalContext).WithExecuterContext(context);

                var operationType = ExtensionsManager.TryGetOperation(actionStatement.ActionName.Namespace, actionStatement.ActionName.Name);
                if (operationType == null)
                {
                    context.LogScope.Log(LogLevel.Error, $"Unable to resolve operation \"{actionStatement.ActionName}\". A Hedgehog extension may be missing.");
                    return(ExecutionStatus.Fault);
                }

                var operation = (Operation)Activator.CreateInstance(operationType);
                await ScriptPropertyMapper.SetPropertiesAsync(operation, actionStatement, rompContext, context);

                var loggedStatus = ExecutionStatus.Normal;
                var logScopeName = Operation.GetLogScopeName(operationType, actionStatement);
                var scopedLogger = new RompScopedLogger(this, context.LogScope.Current.Push(logScopeName), context.LogScope);
                scopedLogger.BeginScope();

                operation.MessageLogged +=
                    (s, e) =>
                {
                    if (e.Level >= MessageLevel.Warning && loggedStatus < ExecutionStatus.Error)
                    {
                        if (e.Level == MessageLevel.Error)
                        {
                            loggedStatus = ExecutionStatus.Error;
                        }
                        else if (e.Level == MessageLevel.Warning)
                        {
                            loggedStatus = ExecutionStatus.Warning;
                        }
                    }

                    scopedLogger.Log(e.Level, e.Message);
                };

                try
                {
                    var asyncOperation = operation as IExecutingOperation ?? throw new InvalidOperationException();

                    context.SetReportProgressDelegate(() => operation.GetProgress()?.StatementProgress ?? default);
                    await asyncOperation.ExecuteAsync(rompContext).ConfigureAwait(false);

                    ScriptPropertyMapper.ReadOutputs(operation, actionStatement.OutArguments, context);

                    return(loggedStatus);
                }
                catch (ExecutionFailureException ex)
                {
                    if (!string.IsNullOrEmpty(ex.Message))
                    {
                        operation.LogError(ex.Message);
                    }

                    throw new ExecutionFailureException(ex.Message);
                }
                catch (Exception ex)
                {
                    if (ex is OperationCanceledException)
                    {
                        operation.LogError("Operation canceled or timeout expired.");
                        return(ExecutionStatus.Fault);
                    }

                    metric.Error = ex;
                    operation.LogError("Unhandled exception: " + ex.ToString());
                    return(ExecutionStatus.Error);
                }
                finally
                {
                    scopedLogger.EndScope();
                }
            }
            finally
            {
                if (RompConfig.CeipEnabled)
                {
                    EventMetric.Write(metric);
                }
            }
        }