コード例 #1
0
        public string ResolveVariables(
            Script script, DeploymentPlanStep planStep, DeploymentJob job, string environmentName,
            short?targetGroupID       = null, int?targetGroupEnvironmentID = null, int?projectTargetID       = null,
            string targetComputerName = null, string credentialUsername    = null, string credentialPassword = null)
        {
            if (script.Body.IsNullOrWhiteSpace())
            {
                throw new ArgumentException("Script body is empty.");
            }

            List <Variable> variables;

            using (var uow = _unitOfWorkFactory.Create())
            {
                variables = uow.Repository <Variable>()
                            .Get(v =>
                                 v.ScopeKey == VariableScope.Global.ToString() ||
                                 (v.ScopeKey == VariableScope.Project.ToString() &&
                                  v.ScopeID == job.ProjectID) ||
                                 (v.ScopeKey == VariableScope.TargetGroup.ToString() &&
                                  v.ScopeID == targetGroupID) ||
                                 (v.ScopeKey == VariableScope.Environment.ToString() &&
                                  v.ScopeID == job.ProjectEnvironmentID) ||
                                 (v.ScopeKey == VariableScope.TargetGroupEnvironment.ToString() &&
                                  v.ScopeID == targetGroupEnvironmentID) ||
                                 (v.ScopeKey == VariableScope.ProjectTarget.ToString() &&
                                  v.ScopeID == projectTargetID) ||
                                 (v.ScopeKey == VariableScope.DeploymentPlan.ToString() &&
                                  v.ScopeID == planStep.DeploymentPlanID) ||
                                 (v.ScopeKey == VariableScope.DeploymentStep.ToString() &&
                                  v.ScopeID == planStep.DeploymentPlanStepID) ||
                                 (v.ScopeKey == VariableScope.DeploymentJob.ToString() &&
                                  v.ScopeID == job.DeploymentJobID))
                            .OrderByDescending(v => v.Scope) // First enum value (Global) has lowest precedence.
                            .ToList();
            }

            var parameters = script.Parameters
                             .OrderBy(v => v.Name)
                             .ToList();

            parameters.Add(new ScriptParameter {
                Name = VariableHelper.DeploymentJobNumberVariable
            });
            parameters.Add(new ScriptParameter {
                Name = VariableHelper.ProductVersionVariable
            });
            parameters.Add(new ScriptParameter {
                Name = VariableHelper.EnvironmentNameVariable
            });
            parameters.Add(new ScriptParameter {
                Name = VariableHelper.TargetComputerNameVariable
            });
            parameters.Add(new ScriptParameter {
                Name = VariableHelper.CredentialUsernameVariable
            });
            parameters.Add(new ScriptParameter {
                Name = VariableHelper.CredentialPasswordVariable
            });

            // Replace variable placeholders with values in multiple passes
            // to enable using variables inside other variables.
            var cyclesLeft   = 10;
            var originalBody = script.Body;

            while (true)
            {
                var processedBody = this.ReplacePlaceholders(originalBody, script.Name, parameters, variables,
                                                             job, environmentName, targetComputerName, credentialUsername, credentialPassword);

                if (processedBody == originalBody)  // Nothing left to replace
                {
                    return(processedBody);
                }

                originalBody = processedBody;

                if (--cyclesLeft == 0)
                {
                    throw new Exception("Possible cyclic reference in variables.");
                }
            }
        }
        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);
                    }
                }
            }
        }