Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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
            });
        }