public LiveTestResponse MakeResponse(CommandExecutionResult commandResult, IServiceTracer tracer, IList<DynamicObjectTransform> transforms, Logger logger)
        {
            LiveTestResponse response = MakeBaseResponse();
            if (commandResult.HadErrors)
            {
                if (logger != null)
                {
                    logger.LogAsync("Command failed with errors.");
                    commandResult.LogErrors(logger);
                }

                response.Error = new LiveTestError();
                response.Error.Code = InvalidRequest;
                List<object> errors = new List<object>();
                foreach (object originalError in commandResult.Errors)
                {
                    errors.AddRange(TransformObject(originalError, transforms));
                }

                response.Error.Data = errors.Count == 0 ? null : errors.Count == 1 ? errors[0] : errors;
                if (this.HttpResponse)
                {
                    HttpResponseMessage responseMessage = tracer.HttpResponses.LastOrDefault();
                    if (responseMessage != null)
                    {
                        // Kill the Content property - doesn't work with Newtonsoft.Json serialization
                        HttpResponseMessage clonedMessage = new HttpResponseMessage(responseMessage.StatusCode);
                        foreach (var header in responseMessage.Headers)
                        {
                            clonedMessage.Headers.Add(header.Key, header.Value);
                        }

                        clonedMessage.ReasonPhrase = responseMessage.ReasonPhrase;
                        clonedMessage.RequestMessage = responseMessage.RequestMessage;
                        clonedMessage.Version = responseMessage.Version;
                        response.Error.HttpResponse = clonedMessage;
                    }
                }
            }
            else
            {
                if (logger != null)
                {
                    logger.LogAsync("Command executed successfully.");
                }

                List<object> results = new List<object>();
                foreach (object originalResult in commandResult.Results)
                {
                    results.AddRange(TransformObject(originalResult, transforms));
                }

                response.Result = GetLiveTestResult(results, tracer);
            }

            return response;
        }
        /// <summary>
        /// Logs in using Azure ServicePrincipal information.
        /// </summary>
        /// <param name="command">Uses the runspace from this ICommandBuilder.</param>
        public void Process(ICommandBuilder command)
        {
            if (String.IsNullOrEmpty(this.TenantId) || String.IsNullOrEmpty(this.ClientId) || String.IsNullOrEmpty(this.Secret))
            {
                throw new InvalidTestCredentialsException();
            }

            // First import the expected module containing Add-AzureRmAccount
            ICommandBuilder importAzureModule = command.Runspace.CreateCommand();

            importAzureModule.Command = "Import-Module";
            importAzureModule.AddParameter("Name", "AzureRM.Profile");
            CommandExecutionResult importAzureModuleResult = importAzureModule.Invoke();

            if (importAzureModuleResult.HadErrors)
            {
                importAzureModuleResult.LogErrors(this.logger);
                throw new CommandFailedException(importAzureModule, importAzureModuleResult);
            }

            // Now run Add-AzureRmAccount
            ICommandBuilder addAzureRmAccount = command.Runspace.CreateCommand();

            addAzureRmAccount.Command = "Add-AzureRmAccount";
            SecureString ss = new SecureString();

            foreach (char c in this.Secret)
            {
                ss.AppendChar(c);
            }

            PSCredential credential = new PSCredential(this.ClientId, ss);

            addAzureRmAccount.AddParameter("Credential", credential);
            addAzureRmAccount.AddParameter("TenantId", this.TenantId);
            addAzureRmAccount.AddParameter("ServicePrincipal", true);
            CommandExecutionResult addAzureRmAccountResult = addAzureRmAccount.Invoke();

            if (addAzureRmAccountResult.HadErrors)
            {
                addAzureRmAccountResult.LogErrors(this.logger);
                throw new CommandFailedException(addAzureRmAccount, addAzureRmAccountResult);
            }
        }
Exemple #3
0
        static void Main(string[] args)
        {
            ServerArgs serverArgs = new ServerArgs().Parse(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.json")).Parse(args).Validate();

            EventLogOutputPipe eventLogOutputPipe = new EventLogOutputPipe();
            CompositeLogger    logger             = new CompositeLogger();

            if (serverArgs.EnableEventLog)
            {
                logger.AddLogger(new Logger(eventLogOutputPipe, eventLogOutputPipe));
            }

            if (serverArgs.EnablePipeLog)
            {
                try
                {
                    NamedPipeServer namedPipe       = new NamedPipeServer(serverArgs.LogPipeName);
                    Logger          namedPipeLogger = new Logger(namedPipe, namedPipe);
                    logger.AddLogger(namedPipeLogger);
                }
                catch (Exception e)
                {
                    logger.LogError("Failed to initialize named pipe logger: " + e.Message);
                }
            }

            if (serverArgs.Errors.Count > 0)
            {
                logger.LogError("Server arguments had errors.");
                foreach (string error in serverArgs.Errors)
                {
                    logger.LogError(error);
                }
                return;
            }

            // Load external modules
            PowerShellRunspace runspace = new PowerShellRunspace(logger);

            foreach (string externalModule in serverArgs.ExternalModules)
            {
                GeneratedModule module = new GeneratedModule(runspace);
                module.ModulePath = externalModule;
                CommandExecutionResult result = module.Load();
                if (result != null && result.HadErrors)
                {
                    logger.LogError(String.Format(CultureInfo.CurrentCulture, "Failed to load extra module: {0}", externalModule));
                    result.LogErrors(logger);
                    return;
                }
            }

            // Start test server
            JsonRpcPipe    jsonRpcPipe = new JsonRpcPipe(new StandardInputPipe(), new StandardOutputPipe());
            LiveTestServer server      = new LiveTestServer(new LiveTestServerStartParams()
            {
                Logger             = logger,
                Input              = jsonRpcPipe,
                Output             = jsonRpcPipe,
                CredentialFactory  = new LiveTestCredentialFactory(),
                RunspaceManager    = runspace,
                ModulePath         = serverArgs.ModulePath,
                TracingManager     = new ServiceTracingManager(),
                SpecificationPaths = serverArgs.SpecificationPaths,
                ObjectTransforms   = serverArgs.GetTransforms()
            });

            try
            {
                server.RunAsync().Wait();
            } catch (Exception ex)
            {
                logger.LogError("Failed to start server: " + ex.ToString());
            }

            // Wait until server exits (usually means the server ran into an internal error)
            while (server.IsRunning)
            {
                Thread.Sleep(2);
            }
        }
        public GeneratedModule GetModuleInfo(string modulePath)
        {
            if (this.logger != null)
            {
                this.logger.LogAsync(String.Format(CultureInfo.CurrentCulture, "Parsing module: {0}", modulePath));
            }
            string          moduleName = String.Empty;
            GeneratedModule module     = new GeneratedModule(this);

            module.ModulePath = modulePath;
            if (File.Exists(modulePath) || Directory.Exists(modulePath))
            {
                // First we have to run Test-ModuleManifest to get RequiredModules
                if (!Path.IsPathRooted(modulePath))
                {
                    throw new ModulePathNotRootedException(modulePath);
                }

                ICommandBuilder testModuleManifest = this.CreateCommand();
                testModuleManifest.Command = "Test-ModuleManifest";
                testModuleManifest.AddParameter("Path", modulePath);
                // Note that this returns errors, but RequiredModules is still filled out.
                CommandExecutionResult result = testModuleManifest.Invoke();

                PSModuleInfo testResult = result.Results.FirstOrDefault() as PSModuleInfo;
                if (testResult == null)
                {
                    if (this.logger != null)
                    {
                        this.logger.LogError("No module object was returned by Test-ModuleManifest.");
                    }
                    throw new CommandFailedException(testModuleManifest, result, "Can't get module information for an invalid module.");
                }

                moduleName = testResult.Name;
                foreach (PSModuleInfo requiredModule in testResult.RequiredModules)
                {
                    GeneratedModule requiredModuleInfo = new GeneratedModule(this);
                    requiredModuleInfo.ModulePath = requiredModule.Name;
                    module.RequiredModules.Add(requiredModuleInfo);
                }
            }
            else
            {
                // Otherwise assume the input is a module name instead of a path and attempt a direct load
                moduleName = modulePath;
            }

            if (this.logger != null)
            {
                this.logger.LogAsync(String.Format(CultureInfo.CurrentCulture, "Loading module: {0}", moduleName));
            }
            CommandExecutionResult loadResult = module.Load();

            if (loadResult.HadErrors)
            {
                loadResult.LogErrors(this.logger);
                throw new CommandFailedException(null, loadResult, "Failed to load module.");
            }

            ICommandBuilder getModule = this.CreateCommand();

            getModule.Command = "Get-Module";
            getModule.AddParameter("Name", moduleName);
            CommandExecutionResult getModuleResult = getModule.Invoke();

            if (getModuleResult.HadErrors)
            {
                getModuleResult.LogErrors(this.logger);
                throw new CommandFailedException(getModule, getModuleResult, "Failed to get module after loading.");
            }

            PSModuleInfo moduleInfo = getModuleResult.Results.First() as PSModuleInfo;

            foreach (string entry in moduleInfo.ExportedFunctions.Keys)
            {
                FunctionInfo commandInfo    = moduleInfo.ExportedFunctions[entry] as FunctionInfo;
                PSTypeName   outputTypeName = null;
                if (commandInfo.OutputType != null && commandInfo.OutputType.Count > 0)
                {
                    // For now PSSwagger only takes the first response
                    outputTypeName = commandInfo.OutputType.First();
                }

                if (this.logger != null)
                {
                    this.logger.LogAsync("Parsing command: " + entry);
                }

                if (commandInfo != null)
                {
                    foreach (CommandParameterSetInfo parameterSet in commandInfo.ParameterSets)
                    {
                        OperationData operationData = new OperationData(parameterSet.Name, entry);
                        if (this.logger != null)
                        {
                            this.logger.LogAsync("Found operation: " + parameterSet.Name);
                        }
                        foreach (CommandParameterInfo commandParameterInfo in parameterSet.Parameters)
                        {
                            ParameterData parameterData = new ParameterData();
                            parameterData.Name = commandParameterInfo.Name.ToLowerInvariant();
                            parameterData.Type = new RuntimeTypeData(commandParameterInfo.ParameterType);
                            operationData.Parameters.Add(parameterData.Name.ToLowerInvariant(), parameterData);
                        }

                        if (outputTypeName != null)
                        {
                            operationData.ResponseType = new ResponseTypeData()
                            {
                                ModuleData = new RuntimeTypeData(outputTypeName.Type)
                            };
                        }

                        module.Operations[operationData.OperationId.ToLowerInvariant()] = operationData;
                    }
                }
            }

            return(module);
        }