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); } } } }