Example #1
0
        public HttpResponseMessage Post(ScriptJobDescriptor descriptor)
        {
            if (!ModelState.IsValid)
            {
                return(Request.CreateResponse(HttpStatusCode.BadRequest, this.GetValidationErrorMessages()));
            }

            var result = _scriptExecutionService.ExecuteScript(descriptor);

            return(Request.CreateResponse(HttpStatusCode.OK, result));
        }
        private bool IsSuccessful(ScriptJobDescriptor descriptor, string output)
        {
            if (!output.IsNullOrWhiteSpace())
            {
                output = output.ToUpperInvariant();  // Prepare for case-insensitive comparison.
            }
            var isSuccessful = true;

            if (!descriptor.SuccessKeywords.IsNullOrWhiteSpace())
            {
                isSuccessful = false;  // We'll have to prove it's successful.

                if (!output.IsNullOrWhiteSpace())
                {
                    var lines = this.PrepareLines(descriptor.SuccessKeywords);
                    if (!lines.IsNullOrEmpty())
                    {
                        if ((descriptor.SuccessKeywordsAllRequired && lines.All(l => output.Contains(l))) ||
                            (!descriptor.SuccessKeywordsAllRequired && lines.Any(l => output.Contains(l))))
                        {
                            isSuccessful = true;
                        }
                    }
                }
            }

            if (!descriptor.FailureKeywords.IsNullOrWhiteSpace() &&
                !output.IsNullOrWhiteSpace())
            {
                var lines = this.PrepareLines(descriptor.FailureKeywords);
                if (!lines.IsNullOrEmpty())
                {
                    if ((descriptor.FailureKeywordsAllRequired && lines.All(l => output.Contains(l))) ||
                        (!descriptor.FailureKeywordsAllRequired && lines.Any(l => output.Contains(l))))
                    {
                        isSuccessful = false;
                    }
                }
            }

            return(isSuccessful);
        }
        public ScriptExecutionResult ExecuteScript(ScriptJobDescriptor descriptor)
        {
            var result = new ScriptExecutionResult();

            try
            {
                var scriptType = descriptor.ScriptType.ToEnum <ScriptType>();
                var scriptBody = descriptor.ScriptBody;

                if (descriptor.RemoteExecution)
                {
                    if (!descriptor.TargetID.HasValue)
                    {
                        throw new Exception("Target not specified.");
                    }
                    var target = _targetService.GetByKey(descriptor.TargetID.Value);

                    result.Output = this.ExecuteScriptRemotely(scriptBody, scriptType,
                                                               target.ComputerName, target.PortNumber, target.TargetKey);
                }
                else
                {
                    result.Output = this.ExecuteScriptLocally(scriptBody, scriptType);
                }

                result.IsSuccessful = this.IsSuccessful(descriptor, result.Output);
            }
            catch (Exception ex)
            {
                Log.Exception(ex);

                foreach (var error in ex.GetExceptionTreeAsFlatList())
                {
                    result.Output += error.Message + Environment.NewLine;
                    result.Output += error.StackTrace;
                }
            }

            return(result);
        }
        private void ExecuteDeploymentStepOnTargets(
            Script script, DeploymentPlanStep planStep, DeploymentJob job, string environmentName,
            int deploymentJobStepID, params short[] targetGroupIDs)
        {
            foreach (var targetGroupID in targetGroupIDs)
            {
                var targetGroupEnvironmentID = _targetGroupEnvironmentService
                                               .GetCombinationID(targetGroupID, job.ProjectEnvironmentID);

                var projectTargets = _projectTargetService
                                     .GetAllForTargetGroupAndEnvironment(targetGroupID, job.ProjectEnvironmentID)
                                     .OrderBy(t => t.Target.Name)
                                     .ToList();

                foreach (var projectTarget in projectTargets)
                {
                    var targetID = projectTarget.TargetID;

                    var jobStepTarget = new DeploymentJobStepTarget
                    {
                        DeploymentJobStepID = deploymentJobStepID,
                        TargetID            = targetID,
                        Status             = DeploymentStatus.Running,
                        StartTime          = DateTime.UtcNow,
                        ExecutionReference = Guid.NewGuid()
                    };
                    _deploymentJobStepTargetService.Insert(jobStepTarget);

                    var target = _targetService.GetWithCredential(targetID);

                    try
                    {
                        var username     = target.UsernameWithDomain;
                        var password     = _credentialService.DecryptPassword(target.Credential.Password);
                        var tempPassword = Guid.NewGuid().ToString();

                        var scriptBody = _variableService.ResolveVariables(script, planStep, job, environmentName,
                                                                           targetGroupID, targetGroupEnvironmentID, projectTarget.ProjectTargetID,
                                                                           target.ComputerName, username, tempPassword);

                        // Don't log real password.
                        jobStepTarget.ExecutedScript  = scriptBody.Replace(tempPassword, "**********");
                        jobStepTarget.ExecutionOutput = "Waiting for output...";
                        _deploymentJobStepTargetService.Update(jobStepTarget);

                        scriptBody = scriptBody.Replace(tempPassword, password);

                        var descriptor = new ScriptJobDescriptor
                        {
                            ScriptType      = script.ScriptType,
                            ScriptBody      = scriptBody,
                            SuccessKeywords = script.SuccessKeywords,
                            FailureKeywords = script.FailureKeywords,
                            RemoteExecution = planStep.RemoteExecution,
                            TargetID        = target.TargetID
                        };
                        var result = _scriptExecutionService.ExecuteScript(descriptor);

                        jobStepTarget.ExecutionOutput = result.Output;
                        if (!result.IsSuccessful)
                        {
                            throw new Exception("Script execution on target [{0}] was not successful."
                                                .FormatString(target.Name));
                        }

                        jobStepTarget.Status = DeploymentStatus.Finished;
                    }
                    catch (Exception ex)
                    {
                        jobStepTarget.Status = DeploymentStatus.Failed;
                        throw new Exception("Deployment step [{0}] failed for target [{1}]."
                                            .FormatString(planStep.Name, target.Name), ex);
                    }
                    finally
                    {
                        jobStepTarget.EndTime = DateTime.UtcNow;
                        _deploymentJobStepTargetService.Update(jobStepTarget);
                    }
                }
            }
        }
        private void ExecuteDeploymentSteps(DeploymentJob job)
        {
            var planSteps = _deploymentPlanStepService.GetEnabledForDeploymentPlan(job.DeploymentPlanID)
                            .OrderBy(s => s.ExecutionOrder)
                            .ToList();

            if (planSteps.IsNullOrEmpty())
            {
                return;
            }

            var targetGroupIDs = _targetGroupService.GetAllForProject(job.ProjectID)
                                 .OrderBy(g => g.Name)
                                 .Select(g => g.TargetGroupID)
                                 .ToArray();

            var environmentName = _projectEnvironmentService.GetByKey(job.ProjectEnvironmentID)
                                  .Name;

            foreach (var planStep in planSteps)
            {
                var jobStep = new DeploymentJobStep
                {
                    DeploymentJobID      = job.DeploymentJobID,
                    DeploymentPlanStepID = planStep.DeploymentPlanStepID,
                    Status             = DeploymentStatus.Running,
                    StartTime          = DateTime.UtcNow,
                    ExecutionReference = Guid.NewGuid()
                };
                _deploymentJobStepService.Insert(jobStep);

                try
                {
                    var script = _scriptService.GetWithParameters(planStep.ScriptID);

                    if (planStep.AllTargetGroups)
                    {
                        this.ExecuteDeploymentStepOnTargets(script, planStep, job, environmentName,
                                                            jobStep.DeploymentJobStepID, targetGroupIDs);
                    }
                    else if (planStep.TargetGroupID.HasValue)
                    {
                        this.ExecuteDeploymentStepOnTargets(script, planStep, job, environmentName,
                                                            jobStep.DeploymentJobStepID, planStep.TargetGroupID.Value);
                    }
                    else  // Execute on deployment server
                    {
                        jobStep.ExecutedScript = _variableService.ResolveVariables(
                            script, planStep, job, environmentName);
                        jobStep.ExecutionOutput = "Waiting for output...";
                        _deploymentJobStepService.Update(jobStep);

                        var descriptor = new ScriptJobDescriptor
                        {
                            ScriptType      = script.ScriptType,
                            ScriptBody      = jobStep.ExecutedScript,
                            SuccessKeywords = script.SuccessKeywords,
                            FailureKeywords = script.FailureKeywords
                        };
                        var result = _scriptExecutionService.ExecuteScript(descriptor);

                        jobStep.ExecutionOutput = result.Output;
                        if (!result.IsSuccessful)
                        {
                            throw new Exception("Script execution on deployment server was not successful.");
                        }
                    }

                    jobStep.Status = DeploymentStatus.Finished;
                }
                catch (Exception ex)
                {
                    jobStep.Status = DeploymentStatus.Failed;
                    throw new Exception("Deployment step [{0}] failed.".FormatString(planStep.Name), ex);
                }
                finally
                {
                    jobStep.EndTime = DateTime.UtcNow;
                    _deploymentJobStepService.Update(jobStep);
                }
            }
        }