diff --git a/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevOpsFindEnvironment_v1.cs b/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevOpsFindEnvironment_v1.cs index 93b1c99..ea4d4f7 100644 --- a/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevOpsFindEnvironment_v1.cs +++ b/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevOpsFindEnvironment_v1.cs @@ -44,6 +44,10 @@ public NoxActionMetaData Discover() ["is-found"] = new NoxActionOutput { Id = "is-found", Description = "A boolean indicating if the environment was found.", + }, + ["environment-id"] = new NoxActionOutput { + Id = "environment-id", + Description = "The Id of the Azure devops environment. Will return null if it does not exist.", } } }; @@ -82,9 +86,12 @@ public async Task> ProcessAsync(INoxWorkflowContext { outputs["is-found"] = false; var environments = await _agentClient.GetEnvironmentsAsync(_projectId.Value); - if (environments.Any(env => env.Name.Equals(_envName, StringComparison.OrdinalIgnoreCase))) + var env = environments.FirstOrDefault(env => env.Name.Equals(_envName, StringComparison.OrdinalIgnoreCase)); + + if (env != null) { outputs["is-found"] = true; + outputs["environment-id"] = env.Id; } ctx.SetState(ActionState.Success); diff --git a/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevopsAuthorizeEnvironmentPipeline_v1.cs b/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevopsAuthorizeEnvironmentPipeline_v1.cs new file mode 100644 index 0000000..61591fd --- /dev/null +++ b/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/AzDevopsAuthorizeEnvironmentPipeline_v1.cs @@ -0,0 +1,113 @@ +using Microsoft.VisualStudio.Services.WebApi; +using Nox.Cli.Abstractions; +using Nox.Cli.Abstractions.Extensions; +using Nox.Cli.Plugin.AzDevOps.Clients; + +namespace Nox.Cli.Plugin.AzDevOps; + +public class AzDevopsAuthorizeEnvironmentPipeline_v1 : INoxCliAddin +{ + public NoxActionMetaData Discover() + { + return new NoxActionMetaData + { + Name = "azdevops/authorize-environment-pipeline@v1", + Author = "Jan Schutte", + Description = "Authorize a pipeline to use an environment", + + Inputs = + { + ["server"] = new NoxActionInput { + Id = "server", + Description = "The DevOps server hostname or IP", + Default = "localhost", + IsRequired = true + }, + + ["personal-access-token"] = new NoxActionInput { + Id = "personal-access-token", + Description = "The personal access token to connect to DevOps with", + Default = string.Empty, + IsRequired = true + }, + + ["project-id"] = new NoxActionInput { + Id = "project-id", + Description = "The project Id (Guid) of the devops project", + Default = Guid.Empty, + IsRequired = true + }, + + ["environment-id"] = new NoxActionInput { + Id = "environment-id", + Description = "The Id (int) of the environment to operate on", + Default = 0, + IsRequired = true + }, + ["pipeline-id"] = new NoxActionInput { + Id = "pipeline-id", + Description = "The Id (int) of the DevOps pipeline to authorize", + Default = 0, + IsRequired = true + } + } + }; + } + + private string? _server; + private string? _pat; + private Guid? _projectId; + private int? _environmentId; + private int? _pipelineId; + private bool _isServerContext = false; + + public Task BeginAsync(IDictionary inputs) + { + var connection = inputs.Value("connection"); + _server = inputs.Value("server"); + _pat = inputs.Value("personal-access-token"); + _projectId = inputs.Value("project-id"); + _pipelineId = inputs.Value("pipeline-id"); + _environmentId = inputs.Value("environment-id"); + return Task.CompletedTask; + } + + public async Task> ProcessAsync(INoxWorkflowContext ctx) + { + _isServerContext = ctx.IsServer; + var outputs = new Dictionary(); + + ctx.SetState(ActionState.Error); + + if (string.IsNullOrWhiteSpace(_server) || + string.IsNullOrWhiteSpace(_pat) || + _projectId == null || + _projectId == Guid.Empty || + _environmentId == null || + _environmentId == 0 || + _pipelineId == null || + _pipelineId == 0 ) + { + ctx.SetErrorMessage("The devops authorize-environment-pipeline action was not initialized"); + } + else + { + try + { + var client = new PipelineClient(_server, _pat); + await client.AuthorizeEnvironmentPipeline(_projectId.Value, _environmentId.Value, _pipelineId.Value); + ctx.SetState(ActionState.Success); + } + catch (Exception ex) + { + ctx.SetErrorMessage(ex.Message); + } + } + return outputs; + } + + public Task EndAsync() + { + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/Clients/PipelineClient.cs b/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/Clients/PipelineClient.cs index 06bc555..7d0b946 100644 --- a/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/Clients/PipelineClient.cs +++ b/src/Nox.Cli.Plugins/Nox.Cli.Plugin.AzDevOps/Clients/PipelineClient.cs @@ -71,8 +71,32 @@ public async Task AuthorizeEndpointPipeline(Guid projectId, Guid endpointId, int throw new DevOpsClientException($"An error occurred while trying to authorize the pipelines on a project ({response.ErrorMessage})"); } } - - + + public async Task AuthorizeEnvironmentPipeline(Guid projectId, int environmentId, int pipelineId) + { + var request = new RestRequest($"/{projectId}/_apis/pipelines/pipelinePermissions/environment/{environmentId}") + { + Method = Method.Patch + }; + AddHeaders(request); + var payload = new AuthorizeRequest() + { + Pipelines = new List + { + new PipelineAuthorize + { + Id = pipelineId, + Authorized = true + } + } + }; + request.AddJsonBody(JsonSerializer.Serialize(payload, JsonOptions.Instance)); + var response = await _client.ExecuteAsync(request); + if (!response.IsSuccessStatusCode) + { + throw new DevOpsClientException($"An error occurred while trying to authorize the pipeline environment on a project ({response.ErrorMessage})"); + } + } private void AddHeaders(RestRequest request) {