private async Task <bool> DoWork(Domain.Models.Run run) { var projectId = run.Workspace.Directory.ProjectId; var dynamicHost = run.Workspace.DynamicHost; Host host = null; _plan = await CreatePlan(run); var workspace = run.Workspace; var files = await _db.GetWorkspaceFiles(workspace, workspace.Directory); var workingDir = workspace.GetPath(_options.RootWorkingDirectory); if (dynamicHost) { // check if host already selected for this workspace if (workspace.HostId.HasValue) { host = workspace.Host; } else { // select a host. multiply by 1.0 to cast as double host = await _db.Hosts .Where(h => h.ProjectId == projectId && h.Enabled && !h.Development) .OrderBy(h => (h.Machines.Count * 1.0 / h.MaximumMachines * 1.0) * 100.0).FirstOrDefaultAsync(); } if (host == null) { _output.AddLine("No Host could be found to use for this Plan"); return(true); } else { _output.AddLine($"Attempting to use Host {host.Name} for this Plan"); } files.Add(host.GetHostFile()); } await workspace.PrepareFileSystem(workingDir, files); _timer = new System.Timers.Timer(_options.OutputSaveInterval); _timer.Elapsed += OnTimedEvent; _timer.Start(); bool isError = false; // Init var initResult = _terraformService.InitializeWorkspace(workspace, OutputHandler); isError = initResult.IsError; if (!isError) { // Plan var planResult = _terraformService.Plan(workspace, run.IsDestroy, run.Targets, OutputHandler); isError = planResult.IsError; } lock (_plan) { _timerComplete = true; _timer.Stop(); } if (dynamicHost) { var result = _terraformService.Show(workspace); isError = result.IsError; if (!isError) { var planOutput = JsonSerializer.Deserialize <PlanOutput>(result.Output, DefaultJsonSettings.Settings); var addedMachines = planOutput.GetAddedMachines(); var hostLock = _lockService.GetHostLock(host.Id); lock (hostLock) { var existingMachines = _db.HostMachines.Where(x => x.HostId == host.Id).ToList(); var addedCount = addedMachines.Count(); if (addedCount + existingMachines.Count < host.MaximumMachines) { List <HostMachine> newMachines = new List <HostMachine>(); foreach (var addedMachine in addedMachines) { var name = addedMachine.Address; if (existingMachines.Any(m => m.WorkspaceId == workspace.Id && m.Name == name)) { continue; } newMachines.Add(new HostMachine { HostId = host.Id, WorkspaceId = workspace.Id, Name = name }); } _db.HostMachines.AddRange(newMachines); workspace.HostId = host.Id; _db.SaveChanges(); _output.AddLine($"Allocated {addedCount} new machines to Host {host.Name}"); } else { _output.AddLine($"{addedCount} new machines exceeds the maximum assigned to Host {host.Name}"); isError = true; } } } } return(isError); }
private async Task <Workspace> OperationDoWork(Workspace workspace, ResourceOperation operation, string[] addresses) { var workingDir = workspace.GetPath(_terraformOptions.RootWorkingDirectory); var files = await _db.GetWorkspaceFiles(workspace, workspace.Directory); await workspace.PrepareFileSystem(workingDir, files); var initResult = _terraformService.InitializeWorkspace( workingDir, workspace.Name, workspace.IsDefault, null); var statePath = string.Empty; if (!workspace.IsDefault) { statePath = workspace.GetStatePath(workingDir, backupState: false); } if (!initResult.IsError) { switch (operation) { case ResourceOperation.taint: case ResourceOperation.untaint: foreach (string address in addresses) { TerraformResult taintResult = null; switch (operation) { case ResourceOperation.taint: taintResult = _terraformService.Taint(workingDir, address, statePath); break; case ResourceOperation.untaint: taintResult = _terraformService.Untaint(workingDir, address, statePath); break; } if (taintResult != null && taintResult.IsError) { _logger.LogError(taintResult.Output); } } break; case ResourceOperation.refresh: TerraformResult refreshResult = _terraformService.Refresh(workingDir, statePath); if (refreshResult.IsError) { _logger.LogError(refreshResult.Output); } break; } await workspace.RetrieveState(workingDir); await _db.SaveChangesAsync(); workspace.CleanupFileSystem(_terraformOptions.RootWorkingDirectory); } return(workspace); }
private async Task <ResourceCommandResult> OperationDoWork(Workspace workspace, ResourceOperation operation, string[] addresses, string args) { var errors = new List <string>(); JsonElement?outputs = null; var workingDir = workspace.GetPath(_terraformOptions.RootWorkingDirectory); var files = await _db.GetWorkspaceFiles(workspace, workspace.Directory); await workspace.PrepareFileSystem(workingDir, files); var initResult = _terraformService.InitializeWorkspace(workspace, null); var statePath = string.Empty; if (!workspace.IsDefault) { statePath = workspace.GetStatePath(workingDir, backupState: false); } if (!initResult.IsError) { TerraformResult result = null; switch (operation) { case ResourceOperation.taint: case ResourceOperation.untaint: foreach (string address in addresses) { TerraformResult taintResult = null; switch (operation) { case ResourceOperation.taint: taintResult = _terraformService.Taint(workspace, address, statePath); break; case ResourceOperation.untaint: taintResult = _terraformService.Untaint(workspace, address, statePath); break; } if (taintResult != null && taintResult.IsError) { errors.Add(taintResult.Output); } } break; case ResourceOperation.refresh: result = _terraformService.Refresh(workspace, statePath); break; case ResourceOperation.remove: result = _terraformService.RemoveResources(workspace, addresses, statePath); break; case ResourceOperation.import: result = _terraformService.Import(workspace, addresses[0], args, statePath); break; case ResourceOperation.output: result = _terraformService.GetOutputs(workspace, statePath); outputs = JsonDocument.Parse(result.Output).RootElement; break; } if (result != null && result.IsError) { errors.Add(result.Output); } await workspace.RetrieveState(workingDir); await _db.SaveChangesAsync(); workspace.CleanupFileSystem(_terraformOptions.RootWorkingDirectory); } return(new ResourceCommandResult { Resources = _mapper.Map <Resource[]>(workspace.GetState().GetResources(), opts => opts.ExcludeMembers(nameof(Resource.Attributes))), Errors = errors.ToArray(), Outputs = outputs }); }