M5: Tags CRUD - model, DTOs, mapper, client, 5 cmdlets + tests
This commit is contained in:
@@ -118,7 +118,12 @@ function Write-Manifest {
|
||||
'Get-InfisicalFolder',
|
||||
'New-InfisicalFolder',
|
||||
'Update-InfisicalFolder',
|
||||
'Remove-InfisicalFolder'
|
||||
'Remove-InfisicalFolder',
|
||||
'Get-InfisicalTags',
|
||||
'Get-InfisicalTag',
|
||||
'New-InfisicalTag',
|
||||
'Update-InfisicalTag',
|
||||
'Remove-InfisicalTag'
|
||||
)
|
||||
AliasesToExport = @()
|
||||
VariablesToExport = @()
|
||||
@@ -178,7 +183,7 @@ if (`$null -eq `$manifest) {
|
||||
|
||||
Import-Module -Name '$($ModuleDirectory.FullName)' -Force
|
||||
|
||||
`$cmds = @('Connect-Infisical','Disconnect-Infisical','Get-InfisicalSecrets','Get-InfisicalSecret','ConvertTo-InfisicalSecretDictionary','Export-InfisicalSecrets','Get-InfisicalProjects','Get-InfisicalProject','New-InfisicalProject','Update-InfisicalProject','Remove-InfisicalProject','Get-InfisicalEnvironments','Get-InfisicalEnvironment','New-InfisicalEnvironment','Update-InfisicalEnvironment','Remove-InfisicalEnvironment','Get-InfisicalFolders','Get-InfisicalFolder','New-InfisicalFolder','Update-InfisicalFolder','Remove-InfisicalFolder')
|
||||
`$cmds = @('Connect-Infisical','Disconnect-Infisical','Get-InfisicalSecrets','Get-InfisicalSecret','ConvertTo-InfisicalSecretDictionary','Export-InfisicalSecrets','Get-InfisicalProjects','Get-InfisicalProject','New-InfisicalProject','Update-InfisicalProject','Remove-InfisicalProject','Get-InfisicalEnvironments','Get-InfisicalEnvironment','New-InfisicalEnvironment','Update-InfisicalEnvironment','Remove-InfisicalEnvironment','Get-InfisicalFolders','Get-InfisicalFolder','New-InfisicalFolder','Update-InfisicalFolder','Remove-InfisicalFolder','Get-InfisicalTags','Get-InfisicalTag','New-InfisicalTag','Update-InfisicalTag','Remove-InfisicalTag')
|
||||
foreach (`$c in `$cmds) {
|
||||
if (-not (Get-Command -Name `$c -Module PSInfisicalAPI -ErrorAction SilentlyContinue)) {
|
||||
throw "Cmdlet not found: `$c"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.Reflection;
|
||||
using PSInfisicalAPI.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace PSInfisicalAPI.Tests
|
||||
{
|
||||
public class TagMapperTests
|
||||
{
|
||||
private static readonly System.Type MapperType = typeof(PSInfisicalAPI.Connections.InfisicalConnection).Assembly
|
||||
.GetType("PSInfisicalAPI.Tags.InfisicalTagMapper", true);
|
||||
|
||||
private static readonly System.Type DtoType = typeof(PSInfisicalAPI.Connections.InfisicalConnection).Assembly
|
||||
.GetType("PSInfisicalAPI.Tags.InfisicalTagResponseDto", true);
|
||||
|
||||
private static InfisicalTag InvokeMap(object dto, string fallbackProjectId)
|
||||
{
|
||||
MethodInfo map = MapperType.GetMethod("Map", BindingFlags.Public | BindingFlags.Static);
|
||||
return (InfisicalTag)map.Invoke(null, new object[] { dto, fallbackProjectId });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Map_Null_Returns_Null()
|
||||
{
|
||||
Assert.Null(InvokeMap(null, "proj-x"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Map_Populates_Fields_With_Explicit_ProjectId()
|
||||
{
|
||||
object dto = System.Activator.CreateInstance(DtoType);
|
||||
DtoType.GetProperty("Id").SetValue(dto, "tag-001");
|
||||
DtoType.GetProperty("Slug").SetValue(dto, "critical");
|
||||
DtoType.GetProperty("Name").SetValue(dto, "Critical");
|
||||
DtoType.GetProperty("Color").SetValue(dto, "#FF0000");
|
||||
DtoType.GetProperty("ProjectId").SetValue(dto, "proj-001");
|
||||
|
||||
InfisicalTag tag = InvokeMap(dto, "fallback-proj");
|
||||
|
||||
Assert.Equal("tag-001", tag.Id);
|
||||
Assert.Equal("critical", tag.Slug);
|
||||
Assert.Equal("Critical", tag.Name);
|
||||
Assert.Equal("#FF0000", tag.Color);
|
||||
Assert.Equal("proj-001", tag.ProjectId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Map_Uses_WorkspaceId_When_ProjectId_Empty()
|
||||
{
|
||||
object dto = System.Activator.CreateInstance(DtoType);
|
||||
DtoType.GetProperty("Id").SetValue(dto, "tag-002");
|
||||
DtoType.GetProperty("WorkspaceId").SetValue(dto, "wks-002");
|
||||
|
||||
InfisicalTag tag = InvokeMap(dto, "fallback-proj");
|
||||
Assert.Equal("wks-002", tag.ProjectId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Map_Uses_Fallback_When_No_ProjectId_Or_WorkspaceId()
|
||||
{
|
||||
object dto = System.Activator.CreateInstance(DtoType);
|
||||
DtoType.GetProperty("Id").SetValue(dto, "tag-003");
|
||||
|
||||
InfisicalTag tag = InvokeMap(dto, "fallback-proj");
|
||||
Assert.Equal("fallback-proj", tag.ProjectId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Map_Falls_Back_To_InternalId_For_Id()
|
||||
{
|
||||
object dto = System.Activator.CreateInstance(DtoType);
|
||||
DtoType.GetProperty("InternalId").SetValue(dto, "internal-tag");
|
||||
|
||||
InfisicalTag tag = InvokeMap(dto, "p");
|
||||
Assert.Equal("internal-tag", tag.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Models;
|
||||
using PSInfisicalAPI.Tags;
|
||||
|
||||
namespace PSInfisicalAPI.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsCommon.Get, "InfisicalTag")]
|
||||
[OutputType(typeof(InfisicalTag))]
|
||||
public sealed class GetInfisicalTagCmdlet : InfisicalCmdletBase
|
||||
{
|
||||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)]
|
||||
[Alias("Slug", "Id")]
|
||||
public string TagSlugOrId { get; set; }
|
||||
|
||||
[Parameter] public string ProjectId { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
InfisicalConnection connection = InfisicalSessionManager.RequireCurrent();
|
||||
InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger);
|
||||
InfisicalTag tag = client.Retrieve(connection, ProjectId, TagSlugOrId);
|
||||
if (tag != null)
|
||||
{
|
||||
WriteObject(tag);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ThrowTerminatingForException("GetInfisicalTagCmdlet", "RetrieveTag", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Models;
|
||||
using PSInfisicalAPI.Tags;
|
||||
|
||||
namespace PSInfisicalAPI.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsCommon.Get, "InfisicalTags")]
|
||||
[OutputType(typeof(InfisicalTag))]
|
||||
public sealed class GetInfisicalTagsCmdlet : InfisicalCmdletBase
|
||||
{
|
||||
[Parameter] public string ProjectId { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
InfisicalConnection connection = InfisicalSessionManager.RequireCurrent();
|
||||
InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger);
|
||||
InfisicalTag[] tags = client.List(connection, ProjectId);
|
||||
foreach (InfisicalTag tag in tags)
|
||||
{
|
||||
WriteObject(tag);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ThrowTerminatingForException("GetInfisicalTagsCmdlet", "ListTags", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Models;
|
||||
using PSInfisicalAPI.Tags;
|
||||
|
||||
namespace PSInfisicalAPI.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsCommon.New, "InfisicalTag", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(InfisicalTag))]
|
||||
public sealed class NewInfisicalTagCmdlet : InfisicalCmdletBase
|
||||
{
|
||||
[Parameter(Mandatory = true, Position = 0)] public string Slug { get; set; }
|
||||
[Parameter] public string Name { get; set; }
|
||||
[Parameter] public string Color { get; set; }
|
||||
[Parameter] public string ProjectId { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldProcess(Slug, "Create Infisical tag"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfisicalConnection connection = InfisicalSessionManager.RequireCurrent();
|
||||
InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger);
|
||||
InfisicalTag tag = client.Create(connection, ProjectId, Slug, Name, Color);
|
||||
if (tag != null)
|
||||
{
|
||||
WriteObject(tag);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ThrowTerminatingForException("NewInfisicalTagCmdlet", "CreateTag", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Tags;
|
||||
|
||||
namespace PSInfisicalAPI.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsCommon.Remove, "InfisicalTag", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
public sealed class RemoveInfisicalTagCmdlet : InfisicalCmdletBase
|
||||
{
|
||||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)]
|
||||
[Alias("Id")]
|
||||
public string TagId { get; set; }
|
||||
|
||||
[Parameter] public string ProjectId { get; set; }
|
||||
[Parameter] public SwitchParameter PassThru { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldProcess(TagId, "Remove Infisical tag"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfisicalConnection connection = InfisicalSessionManager.RequireCurrent();
|
||||
InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger);
|
||||
client.Delete(connection, ProjectId, TagId);
|
||||
|
||||
if (PassThru.IsPresent)
|
||||
{
|
||||
WriteObject(TagId);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ThrowTerminatingForException("RemoveInfisicalTagCmdlet", "DeleteTag", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Models;
|
||||
using PSInfisicalAPI.Tags;
|
||||
|
||||
namespace PSInfisicalAPI.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsData.Update, "InfisicalTag", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(InfisicalTag))]
|
||||
public sealed class UpdateInfisicalTagCmdlet : InfisicalCmdletBase
|
||||
{
|
||||
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, Position = 0)]
|
||||
[Alias("Id")]
|
||||
public string TagId { get; set; }
|
||||
|
||||
[Parameter] public string Slug { get; set; }
|
||||
[Parameter] public string Name { get; set; }
|
||||
[Parameter] public string Color { get; set; }
|
||||
[Parameter] public string ProjectId { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldProcess(TagId, "Update Infisical tag"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfisicalConnection connection = InfisicalSessionManager.RequireCurrent();
|
||||
InfisicalTagClient client = new InfisicalTagClient(HttpClient, Logger);
|
||||
InfisicalTag tag = client.Update(connection, ProjectId, TagId, Slug, Name, Color);
|
||||
if (tag != null)
|
||||
{
|
||||
WriteObject(tag);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ThrowTerminatingForException("UpdateInfisicalTagCmdlet", "UpdateTag", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace PSInfisicalAPI.Models
|
||||
{
|
||||
public sealed class InfisicalTag
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Slug { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Color { get; set; }
|
||||
public string ProjectId { get; set; }
|
||||
public DateTimeOffset? CreatedAtUtc { get; set; }
|
||||
public DateTimeOffset? UpdatedAtUtc { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Slug ?? Name ?? Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PSInfisicalAPI.Connections;
|
||||
using PSInfisicalAPI.Endpoints;
|
||||
using PSInfisicalAPI.Errors;
|
||||
using PSInfisicalAPI.Http;
|
||||
using PSInfisicalAPI.Logging;
|
||||
using PSInfisicalAPI.Models;
|
||||
using PSInfisicalAPI.Serialization;
|
||||
|
||||
namespace PSInfisicalAPI.Tags
|
||||
{
|
||||
public sealed class InfisicalTagClient
|
||||
{
|
||||
private const string Component = "TagClient";
|
||||
|
||||
private readonly IInfisicalLogger _logger;
|
||||
private readonly JsonInfisicalSerializer _serializer;
|
||||
private readonly InfisicalApiInvoker _invoker;
|
||||
|
||||
public InfisicalTagClient(IInfisicalHttpClient httpClient, IInfisicalLogger logger)
|
||||
{
|
||||
if (httpClient == null) { throw new ArgumentNullException(nameof(httpClient)); }
|
||||
_logger = logger ?? NullInfisicalLogger.Instance;
|
||||
_serializer = new JsonInfisicalSerializer();
|
||||
_invoker = new InfisicalApiInvoker(httpClient);
|
||||
}
|
||||
|
||||
public InfisicalTag[] List(InfisicalConnection connection, string projectId)
|
||||
{
|
||||
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
|
||||
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
|
||||
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
|
||||
|
||||
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "projectId", resolvedProjectId } };
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Information(Component, "Attempting to list Infisical tags. Please Wait...");
|
||||
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.ListTags, "ListTags", pathParameters, null, null);
|
||||
InfisicalTagListResponseDto dto = _serializer.Deserialize<InfisicalTagListResponseDto>(response.Body);
|
||||
response.Clear();
|
||||
|
||||
List<InfisicalTagResponseDto> source = dto != null ? (dto.WorkspaceTags ?? dto.Tags) : null;
|
||||
InfisicalTag[] mapped = InfisicalTagMapper.MapMany(source, resolvedProjectId);
|
||||
_logger.Information(Component, "Infisical tag list retrieval was successful.");
|
||||
return mapped;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.Error(Component, "Infisical tag list retrieval failed.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public InfisicalTag Retrieve(InfisicalConnection connection, string projectId, string tagSlugOrId)
|
||||
{
|
||||
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
|
||||
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
|
||||
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
|
||||
if (string.IsNullOrEmpty(tagSlugOrId)) { throw new InfisicalConfigurationException("Tag slug or id is required."); }
|
||||
|
||||
InfisicalTag[] all = List(connection, resolvedProjectId);
|
||||
foreach (InfisicalTag tag in all)
|
||||
{
|
||||
if (string.Equals(tag.Id, tagSlugOrId, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(tag.Slug, tagSlugOrId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public InfisicalTag Create(InfisicalConnection connection, string projectId, string slug, string name, string color)
|
||||
{
|
||||
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
|
||||
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
|
||||
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
|
||||
if (string.IsNullOrEmpty(slug)) { throw new InfisicalConfigurationException("Slug is required."); }
|
||||
|
||||
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "projectId", resolvedProjectId } };
|
||||
InfisicalTagCreateRequestDto request = new InfisicalTagCreateRequestDto { Slug = slug, Name = name, Color = color };
|
||||
string body = _serializer.Serialize(request);
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Information(Component, string.Concat("Attempting to create Infisical tag '", slug, "'. Please Wait..."));
|
||||
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.CreateTag, "CreateTag", pathParameters, null, body);
|
||||
InfisicalTagSingleResponseDto dto = _serializer.Deserialize<InfisicalTagSingleResponseDto>(response.Body);
|
||||
response.Clear();
|
||||
|
||||
InfisicalTagResponseDto inner = dto != null ? (dto.WorkspaceTag ?? dto.Tag) : null;
|
||||
InfisicalTag mapped = InfisicalTagMapper.Map(inner, resolvedProjectId);
|
||||
_logger.Information(Component, "Infisical tag creation was successful.");
|
||||
return mapped;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.Error(Component, "Infisical tag creation failed.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public InfisicalTag Update(InfisicalConnection connection, string projectId, string tagId, string slug, string name, string color)
|
||||
{
|
||||
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
|
||||
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
|
||||
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
|
||||
if (string.IsNullOrEmpty(tagId)) { throw new InfisicalConfigurationException("TagId is required."); }
|
||||
|
||||
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "projectId", resolvedProjectId }, { "tagId", tagId } };
|
||||
InfisicalTagUpdateRequestDto request = new InfisicalTagUpdateRequestDto { Slug = slug, Name = name, Color = color };
|
||||
string body = _serializer.Serialize(request);
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Information(Component, string.Concat("Attempting to update Infisical tag '", tagId, "'. Please Wait..."));
|
||||
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.UpdateTag, "UpdateTag", pathParameters, null, body);
|
||||
InfisicalTagSingleResponseDto dto = _serializer.Deserialize<InfisicalTagSingleResponseDto>(response.Body);
|
||||
response.Clear();
|
||||
|
||||
InfisicalTagResponseDto inner = dto != null ? (dto.WorkspaceTag ?? dto.Tag) : null;
|
||||
InfisicalTag mapped = InfisicalTagMapper.Map(inner, resolvedProjectId);
|
||||
_logger.Information(Component, "Infisical tag update was successful.");
|
||||
return mapped;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.Error(Component, "Infisical tag update failed.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(InfisicalConnection connection, string projectId, string tagId)
|
||||
{
|
||||
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
|
||||
string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
|
||||
if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
|
||||
if (string.IsNullOrEmpty(tagId)) { throw new InfisicalConfigurationException("TagId is required."); }
|
||||
|
||||
Dictionary<string, string> pathParameters = new Dictionary<string, string> { { "projectId", resolvedProjectId }, { "tagId", tagId } };
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Information(Component, string.Concat("Attempting to delete Infisical tag '", tagId, "'. Please Wait..."));
|
||||
InfisicalHttpResponse response = _invoker.Invoke(connection, InfisicalEndpointNames.DeleteTag, "DeleteTag", pathParameters, null, null);
|
||||
response.Clear();
|
||||
_logger.Information(Component, "Infisical tag deletion was successful.");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.Error(Component, "Infisical tag deletion failed.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static string FirstNonEmpty(params string[] values)
|
||||
{
|
||||
if (values == null) { return null; }
|
||||
foreach (string value in values) { if (!string.IsNullOrEmpty(value)) { return value; } }
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PSInfisicalAPI.Tags
|
||||
{
|
||||
internal sealed class InfisicalTagResponseDto
|
||||
{
|
||||
[JsonProperty("id")] public string Id { get; set; }
|
||||
[JsonProperty("_id")] public string InternalId { get; set; }
|
||||
[JsonProperty("slug")] public string Slug { get; set; }
|
||||
[JsonProperty("name")] public string Name { get; set; }
|
||||
[JsonProperty("color")] public string Color { get; set; }
|
||||
[JsonProperty("projectId")] public string ProjectId { get; set; }
|
||||
[JsonProperty("workspaceId")] public string WorkspaceId { get; set; }
|
||||
[JsonProperty("createdAt")] public string CreatedAt { get; set; }
|
||||
[JsonProperty("updatedAt")] public string UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class InfisicalTagListResponseDto
|
||||
{
|
||||
[JsonProperty("workspaceTags")] public List<InfisicalTagResponseDto> WorkspaceTags { get; set; }
|
||||
[JsonProperty("tags")] public List<InfisicalTagResponseDto> Tags { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class InfisicalTagSingleResponseDto
|
||||
{
|
||||
[JsonProperty("workspaceTag")] public InfisicalTagResponseDto WorkspaceTag { get; set; }
|
||||
[JsonProperty("tag")] public InfisicalTagResponseDto Tag { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class InfisicalTagCreateRequestDto
|
||||
{
|
||||
[JsonProperty("slug")] public string Slug { get; set; }
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; set; }
|
||||
[JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] public string Color { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class InfisicalTagUpdateRequestDto
|
||||
{
|
||||
[JsonProperty("slug", NullValueHandling = NullValueHandling.Ignore)] public string Slug { get; set; }
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; set; }
|
||||
[JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] public string Color { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using PSInfisicalAPI.Models;
|
||||
|
||||
namespace PSInfisicalAPI.Tags
|
||||
{
|
||||
internal static class InfisicalTagMapper
|
||||
{
|
||||
public static InfisicalTag Map(InfisicalTagResponseDto dto, string fallbackProjectId)
|
||||
{
|
||||
if (dto == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string projectId = !string.IsNullOrEmpty(dto.ProjectId)
|
||||
? dto.ProjectId
|
||||
: (!string.IsNullOrEmpty(dto.WorkspaceId) ? dto.WorkspaceId : fallbackProjectId);
|
||||
|
||||
return new InfisicalTag
|
||||
{
|
||||
Id = !string.IsNullOrEmpty(dto.Id) ? dto.Id : dto.InternalId,
|
||||
Slug = dto.Slug,
|
||||
Name = dto.Name,
|
||||
Color = dto.Color,
|
||||
ProjectId = projectId,
|
||||
CreatedAtUtc = ParseTimestamp(dto.CreatedAt),
|
||||
UpdatedAtUtc = ParseTimestamp(dto.UpdatedAt)
|
||||
};
|
||||
}
|
||||
|
||||
public static InfisicalTag[] MapMany(IEnumerable<InfisicalTagResponseDto> items, string fallbackProjectId)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
return Array.Empty<InfisicalTag>();
|
||||
}
|
||||
|
||||
List<InfisicalTag> results = new List<InfisicalTag>();
|
||||
foreach (InfisicalTagResponseDto dto in items)
|
||||
{
|
||||
InfisicalTag mapped = Map(dto, fallbackProjectId);
|
||||
if (mapped != null)
|
||||
{
|
||||
results.Add(mapped);
|
||||
}
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
private static DateTimeOffset? ParseTimestamp(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DateTimeOffset parsed;
|
||||
if (DateTimeOffset.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out parsed))
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user