Refactor IPAM model classes to use records for Address, Subnetwork, Vlan, Vrf, Section, Tag, Domain, Nameserver, and Session; enhance documentation and implement value equality for records.

This commit is contained in:
2026-01-19 17:25:18 +03:00
parent 694822f0d6
commit f56784f2aa
44 changed files with 1601 additions and 1905 deletions

View File

@@ -1,24 +1,30 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet("Assign", "Tag")]
public class AssignTagCmdlet : PSCmdlet
/// <summary>
/// Assigns a tag to an address in phpIPAM.
/// </summary>
[Cmdlet("Assign", "Tag", SupportsShouldProcess = true)]
[OutputType(typeof(Address))]
public class AssignTagCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
Position = 0,
HelpMessage = "The address to assign the tag to.")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
[Parameter(
Mandatory = true,
Position = 1)]
Position = 1,
HelpMessage = "The tag to assign.")]
[ValidateNotNullOrEmpty]
public Tag? Tag { get; set; }
@@ -26,14 +32,25 @@ public class AssignTagCmdlet : PSCmdlet
{
try
{
var identifiers = new List<string> { AddressObject!.Id.ToString() };
var identifiers = new[] { AddressObject!.Id.ToString() };
var body = new Dictionary<string, object>
{
{ "tag", Tag!.Id }
["tag"] = Tag!.Id
};
RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
if (ShouldProcess($"Address {AddressObject.Ip}", $"Assign tag '{Tag.Type}'"))
{
RequestHelper.InvokeRequest(
"PATCH", ApiController.Addresses, null, null, body, identifiers
).GetAwaiter().GetResult();
// Return the updated address
var address = RequestHelper.InvokeRequest(
"GET", ApiController.Addresses, ModelType.Address, null, null, identifiers
).GetAwaiter().GetResult();
WriteResult(address);
}
}
catch (Exception ex)
{

View File

@@ -1,21 +1,17 @@
namespace PS.IPAM.Cmdlets;
using System.Management.Automation;
using PS.IPAM.Helpers;
/// <summary>
/// Closes the current phpIPAM API session.
/// </summary>
[Cmdlet(VerbsCommon.Close, "Session")]
public class CloseSessionCmdlet : PSCmdlet
public class CloseSessionCmdlet : BaseCmdlet
{
protected override void ProcessRecord()
{
try
{
RequestHelper.InvokeRequest("DELETE", controllers.user, null, null, null, null)
.GetAwaiter().GetResult();
SessionManager.CloseSession();
}
catch (System.Exception ex)
{
WriteError(new ErrorRecord(ex, "CloseSessionError", ErrorCategory.InvalidOperation, null));
}
SessionManager.CloseSession();
WriteVerbose("Session closed successfully.");
}
}

View File

@@ -1,21 +1,25 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves IP address entries from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Address", DefaultParameterSetName = "ByID")]
[OutputType(typeof(Address))]
public class GetAddressCmdlet : PSCmdlet
public class GetAddressCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The address ID to retrieve.")]
[ValidateNotNullOrEmpty]
public int Id { get; set; }
@@ -24,7 +28,8 @@ public class GetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByIP")]
ParameterSetName = "ByIP",
HelpMessage = "The IP address to search for.")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
@@ -39,7 +44,8 @@ public class GetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByHostName")]
ParameterSetName = "ByHostName",
HelpMessage = "The hostname to search for.")]
[ValidateNotNullOrEmpty]
public string? HostName { get; set; }
@@ -48,7 +54,8 @@ public class GetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByHostBase")]
ParameterSetName = "ByHostBase",
HelpMessage = "The hostname base pattern to search for.")]
[ValidateNotNullOrEmpty]
public string? HostBase { get; set; }
@@ -57,7 +64,8 @@ public class GetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByTag")]
ParameterSetName = "ByTag",
HelpMessage = "The tag ID to filter addresses by.")]
[ValidateNotNullOrEmpty]
public int? TagId { get; set; }
@@ -66,7 +74,8 @@ public class GetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetId")]
ParameterSetName = "BySubnetId",
HelpMessage = "The subnet ID to get addresses from.")]
[ValidateNotNullOrEmpty]
public int? SubnetId { get; set; }
@@ -75,7 +84,8 @@ public class GetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetCIDR")]
ParameterSetName = "BySubnetCIDR",
HelpMessage = "The subnet in CIDR notation to get addresses from.")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? SubnetCIDR { get; set; }
@@ -84,7 +94,7 @@ public class GetAddressCmdlet : PSCmdlet
{
try
{
var controller = controllers.addresses;
var controller = ApiController.Addresses;
var identifiers = new List<string>();
switch (ParameterSetName)
@@ -92,23 +102,28 @@ public class GetAddressCmdlet : PSCmdlet
case "ByID":
identifiers.Add(Id.ToString());
break;
case "ByIP":
identifiers.Add("search");
identifiers.Add(IP!.ToString());
break;
case "ByHostName":
identifiers.Add("search_hostname");
identifiers.Add(HostName!);
break;
case "ByHostBase":
identifiers.Add("search_hostbase");
identifiers.Add(HostBase!);
break;
case "ByTag":
identifiers.Add("tags");
identifiers.Add(TagId!.Value.ToString());
identifiers.Add("addresses");
break;
case "BySubnetId":
if (IP != null)
{
@@ -117,42 +132,34 @@ public class GetAddressCmdlet : PSCmdlet
}
else
{
controller = controllers.subnets;
controller = ApiController.Subnets;
identifiers.Add(SubnetId!.Value.ToString());
identifiers.Add("addresses");
}
break;
case "BySubnetCIDR":
controller = controllers.subnets;
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", SubnetCIDR! })
.GetAwaiter().GetResult();
controller = ApiController.Subnets;
var subnet = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
new[] { "cidr", SubnetCIDR! }
).GetAwaiter().GetResult() as Subnetwork;
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
throw new ItemNotFoundException($"Subnet '{SubnetCIDR}' not found.");
}
var subnetObj = subnet as Subnetwork;
identifiers.Add(subnetObj!.Id.ToString());
identifiers.Add(subnet.Id.ToString());
identifiers.Add("addresses");
break;
}
var result = RequestHelper.InvokeRequest("GET", controller, types.Address, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", controller, ModelType.Address, null, null, identifiers.ToArray()
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,20 +1,23 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Gets the first available IP address in a subnet.
/// </summary>
[Cmdlet(VerbsCommon.Get, "FirstFreeIP", DefaultParameterSetName = "ByID")]
public class GetFirstFreeIPCmdlet : PSCmdlet
public class GetFirstFreeIPCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByCIDR")]
ParameterSetName = "ByCIDR",
HelpMessage = "The subnet in CIDR notation.")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? CIDR { get; set; }
@@ -24,7 +27,8 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The subnet ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -33,7 +37,8 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
ParameterSetName = "BySubnetObject",
HelpMessage = "The subnet object.")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
@@ -41,30 +46,12 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
{
try
{
int subnetId;
if (ParameterSetName == "ByCIDR")
{
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR! })
.GetAwaiter().GetResult();
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
}
var subnetObj = subnet as Subnetwork;
subnetId = subnetObj!.Id;
}
else if (ParameterSetName == "BySubnetObject")
{
subnetId = SubnetObject!.Id;
}
else
{
subnetId = Id!.Value;
}
var subnetId = GetSubnetId();
var identifiers = new List<string> { subnetId.ToString(), "first_free" };
var result = RequestHelper.InvokeRequest("GET", controllers.subnets, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, null, null, null, identifiers.ToArray()
).GetAwaiter().GetResult();
if (result != null)
{
@@ -76,4 +63,28 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
WriteError(new ErrorRecord(ex, "GetFirstFreeIPError", ErrorCategory.InvalidOperation, null));
}
}
private int GetSubnetId()
{
switch (ParameterSetName)
{
case "ByCIDR":
var subnet = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
new[] { "cidr", CIDR! }
).GetAwaiter().GetResult() as Subnetwork;
if (subnet == null)
{
throw new ItemNotFoundException($"Subnet '{CIDR}' not found.");
}
return subnet.Id;
case "BySubnetObject":
return SubnetObject!.Id;
default:
return Id!.Value;
}
}
}

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves L2 domain information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "L2Domain", DefaultParameterSetName = "ByID")]
[OutputType(typeof(Domain))]
public class GetL2DomainCmdlet : PSCmdlet
public class GetL2DomainCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The L2 domain ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -23,28 +27,18 @@ public class GetL2DomainCmdlet : PSCmdlet
try
{
var identifiers = new List<string>();
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
var result = RequestHelper.InvokeRequest("GET", controllers.l2domains, types.Domain, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", ApiController.L2Domains, ModelType.Domain, null, null,
identifiers.Count > 0 ? identifiers.ToArray() : null
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves nameserver information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Nameserver", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Nameserver))]
public class GetNameserverCmdlet : PSCmdlet
public class GetNameserverCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The nameserver ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -23,28 +27,18 @@ public class GetNameserverCmdlet : PSCmdlet
try
{
var identifiers = new List<string>();
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
var result = RequestHelper.InvokeRequest("GET", controllers.tools, types.Nameserver, subcontrollers.nameservers, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", ApiController.Tools, ModelType.Nameserver, ApiSubController.Nameservers,
null, identifiers.Count > 0 ? identifiers.ToArray() : null
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves permission information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Permissions")]
public class GetPermissionsCmdlet : PSCmdlet
public class GetPermissionsCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The address ID.")]
[ValidateNotNullOrEmpty]
public string? Id { get; set; }
@@ -23,7 +27,8 @@ public class GetPermissionsCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByIP")]
ParameterSetName = "ByIP",
HelpMessage = "The IP address to search for.")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
@@ -38,7 +43,8 @@ public class GetPermissionsCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByHostName")]
ParameterSetName = "ByHostName",
HelpMessage = "The hostname to search for.")]
[ValidateNotNullOrEmpty]
public string? HostName { get; set; }
@@ -47,7 +53,8 @@ public class GetPermissionsCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByTag")]
ParameterSetName = "ByTag",
HelpMessage = "The tag ID.")]
[ValidateNotNullOrEmpty]
public string? TagId { get; set; }
@@ -56,7 +63,8 @@ public class GetPermissionsCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetId")]
ParameterSetName = "BySubnetId",
HelpMessage = "The subnet ID.")]
[ValidateNotNullOrEmpty]
public string? SubnetId { get; set; }
@@ -65,7 +73,8 @@ public class GetPermissionsCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetCIDR")]
ParameterSetName = "BySubnetCIDR",
HelpMessage = "The subnet in CIDR notation.")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? SubnetCIDR { get; set; }
@@ -74,7 +83,7 @@ public class GetPermissionsCmdlet : PSCmdlet
{
try
{
var controller = controllers.addresses;
var controller = ApiController.Addresses;
var identifiers = new List<string>();
switch (ParameterSetName)
@@ -82,19 +91,23 @@ public class GetPermissionsCmdlet : PSCmdlet
case "ByID":
identifiers.Add(Id!);
break;
case "ByIP":
identifiers.Add("search");
identifiers.Add(IP!.ToString());
break;
case "ByHostName":
identifiers.Add("search_hostname");
identifiers.Add(HostName!);
break;
case "ByTag":
identifiers.Add("tags");
identifiers.Add(TagId!);
identifiers.Add("addresses");
break;
case "BySubnetId":
if (IP != null)
{
@@ -103,42 +116,34 @@ public class GetPermissionsCmdlet : PSCmdlet
}
else
{
controller = controllers.subnets;
controller = ApiController.Subnets;
identifiers.Add(SubnetId!);
identifiers.Add("addresses");
}
break;
case "BySubnetCIDR":
controller = controllers.subnets;
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", SubnetCIDR! })
.GetAwaiter().GetResult();
controller = ApiController.Subnets;
var subnet = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
new[] { "cidr", SubnetCIDR! }
).GetAwaiter().GetResult() as Subnetwork;
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
throw new ItemNotFoundException($"Subnet '{SubnetCIDR}' not found.");
}
var subnetObj = subnet as Subnetwork;
identifiers.Add(subnetObj!.Id.ToString());
identifiers.Add(subnet.Id.ToString());
identifiers.Add("addresses");
break;
}
var result = RequestHelper.InvokeRequest("GET", controller, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", controller, null, null, null, identifiers.ToArray()
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,19 +1,23 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves section information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Section", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Section))]
public class GetSectionCmdlet : PSCmdlet
public class GetSectionCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The section ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -21,7 +25,8 @@ public class GetSectionCmdlet : PSCmdlet
Mandatory = true,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByName")]
ParameterSetName = "ByName",
HelpMessage = "The section name.")]
[ValidateNotNullOrEmpty]
public string? Name { get; set; }
@@ -30,6 +35,7 @@ public class GetSectionCmdlet : PSCmdlet
try
{
var identifiers = new List<string>();
if (ParameterSetName == "ByID" && Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
@@ -39,23 +45,12 @@ public class GetSectionCmdlet : PSCmdlet
identifiers.Add(Name!);
}
var result = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", ApiController.Sections, ModelType.Section, null, null,
identifiers.Count > 0 ? identifiers.ToArray() : null
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,22 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves subnet information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Subnet", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Subnetwork))]
public class GetSubnetCmdlet : PSCmdlet
public class GetSubnetCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByCIDR")]
ParameterSetName = "ByCIDR",
HelpMessage = "The subnet in CIDR notation (e.g., 192.168.1.0/24).")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? CIDR { get; set; }
@@ -26,7 +28,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The subnet ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -35,7 +38,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySectionId")]
ParameterSetName = "BySectionId",
HelpMessage = "The section ID to get subnets from.")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
@@ -56,7 +60,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySectionName")]
ParameterSetName = "BySectionName",
HelpMessage = "The section name to get subnets from.")]
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
@@ -77,7 +82,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByVrfId")]
ParameterSetName = "ByVrfId",
HelpMessage = "The VRF ID to get subnets from.")]
[ValidateNotNullOrEmpty]
public int? VrfId { get; set; }
@@ -86,7 +92,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByVlanId")]
ParameterSetName = "ByVlanId",
HelpMessage = "The VLAN ID to get subnets from.")]
[ValidateNotNullOrEmpty]
public int? VlanId { get; set; }
@@ -95,7 +102,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByVlanNumber")]
ParameterSetName = "ByVlanNumber",
HelpMessage = "The VLAN number to get subnets from.")]
[ValidateNotNullOrEmpty]
public int? VlanNumber { get; set; }
@@ -104,7 +112,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "Get child subnets (slaves).")]
public SwitchParameter Slaves { get; set; }
[Parameter(
@@ -112,7 +121,8 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "Get child subnets recursively.")]
public SwitchParameter Recurse { get; set; }
[Parameter(
@@ -120,16 +130,16 @@ public class GetSubnetCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1,
ParameterSetName = "ByVlanNumber")]
ParameterSetName = "ByVlanNumber",
HelpMessage = "The L2 domain ID to narrow VLAN search.")]
[ValidateNotNullOrEmpty]
public int? VlanDomainId { get; set; }
protected override void ProcessRecord()
{
try
{
var controller = controllers.subnets;
var controller = ApiController.Subnets;
var identifiers = new List<string>();
switch (ParameterSetName)
@@ -138,6 +148,7 @@ public class GetSubnetCmdlet : PSCmdlet
identifiers.Add("cidr");
identifiers.Add(CIDR!);
break;
case "ByID":
identifiers.Add(Id!.Value.ToString());
if (Slaves.IsPresent)
@@ -145,117 +156,122 @@ public class GetSubnetCmdlet : PSCmdlet
identifiers.Add(Recurse.IsPresent ? "slaves_recursive" : "slaves");
}
break;
case "BySectionId":
controller = controllers.sections;
controller = ApiController.Sections;
identifiers.Add(SectionId!.Value.ToString());
identifiers.Add("subnets");
break;
case "BySectionName":
controller = controllers.sections;
var section = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName! })
.GetAwaiter().GetResult();
if (section == null)
{
throw new Exception("Cannot find section!");
}
var sectionObj = section as Section;
identifiers.Add(sectionObj!.Id.ToString());
controller = ApiController.Sections;
var section = GetSectionByName(SectionName!);
identifiers.Add(section.Id.ToString());
identifiers.Add("subnets");
break;
case "ByVrfId":
controller = controllers.vrf;
controller = ApiController.Vrf;
identifiers.Add(VrfId!.Value.ToString());
identifiers.Add("subnets");
break;
case "ByVlanId":
controller = controllers.vlan;
controller = ApiController.Vlan;
identifiers.Add(VlanId!.Value.ToString());
identifiers.Add("subnets");
if (SectionId.HasValue)
{
identifiers.Add(SectionId.Value.ToString());
}
else if (!string.IsNullOrEmpty(SectionName))
{
var section2 = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName })
.GetAwaiter().GetResult();
if (section2 != null)
{
var sectionObj2 = section2 as Section;
identifiers.Add(sectionObj2!.Id.ToString());
}
}
AddSectionIdentifier(identifiers);
break;
case "ByVlanNumber":
controller = controllers.vlan;
var vlans = RequestHelper.InvokeRequest("GET", controllers.vlan, types.Vlan, null, null, new[] { "search", VlanNumber!.Value.ToString() })
.GetAwaiter().GetResult();
if (vlans == null)
{
throw new Exception("Cannot find Vlan!");
}
var vlanList = vlans as System.Collections.IEnumerable;
Vlan? foundVlan = null;
if (vlanList != null)
{
foreach (var v in vlanList)
{
if (v is Vlan vlan)
{
if (VlanDomainId.HasValue && vlan.DomainId != VlanDomainId.Value)
continue;
if (foundVlan != null)
{
throw new Exception($"More than one vLan with {VlanNumber} number is present!");
}
foundVlan = vlan;
}
}
}
if (foundVlan == null)
{
throw new Exception("Cannot find Vlan!");
}
identifiers.Add(foundVlan.Id.ToString());
controller = ApiController.Vlan;
var vlan = FindVlanByNumber(VlanNumber!.Value, VlanDomainId);
identifiers.Add(vlan.Id.ToString());
identifiers.Add("subnets");
if (SectionId.HasValue)
{
identifiers.Add(SectionId.Value.ToString());
}
else if (!string.IsNullOrEmpty(SectionName))
{
var section3 = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName })
.GetAwaiter().GetResult();
if (section3 != null)
{
var sectionObj3 = section3 as Section;
identifiers.Add(sectionObj3!.Id.ToString());
}
}
AddSectionIdentifier(identifiers);
break;
}
var result = RequestHelper.InvokeRequest("GET", controller, types.Subnetwork, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", controller, ModelType.Subnetwork, null, null, identifiers.ToArray()
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetSubnetError", ErrorCategory.InvalidOperation, null));
}
}
private Section GetSectionByName(string name)
{
var section = RequestHelper.InvokeRequest(
"GET", ApiController.Sections, ModelType.Section, null, null, new[] { name }
).GetAwaiter().GetResult() as Section;
if (section == null)
{
throw new ItemNotFoundException($"Section '{name}' not found.");
}
return section;
}
private Vlan FindVlanByNumber(int number, int? domainId)
{
var vlans = RequestHelper.InvokeRequest(
"GET", ApiController.Vlan, ModelType.Vlan, null, null,
new[] { "search", number.ToString() }
).GetAwaiter().GetResult();
if (vlans == null)
{
throw new ItemNotFoundException($"VLAN {number} not found.");
}
Vlan? foundVlan = null;
if (vlans is System.Collections.IEnumerable enumerable)
{
foreach (var v in enumerable)
{
if (v is Vlan vlan)
{
if (domainId.HasValue && vlan.DomainId != domainId.Value)
{
continue;
}
if (foundVlan != null)
{
throw new InvalidOperationException(
$"Multiple VLANs with number {number} exist. Specify VlanDomainId to narrow the search.");
}
foundVlan = vlan;
}
}
}
if (foundVlan == null)
{
throw new ItemNotFoundException($"VLAN {number} not found.");
}
return foundVlan;
}
private void AddSectionIdentifier(List<string> identifiers)
{
if (SectionId.HasValue)
{
identifiers.Add(SectionId.Value.ToString());
}
else if (!string.IsNullOrEmpty(SectionName))
{
var section = GetSectionByName(SectionName);
identifiers.Add(section.Id.ToString());
}
}
}

View File

@@ -1,20 +1,23 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves subnet usage statistics from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "SubnetUsage", DefaultParameterSetName = "ByID")]
public class GetSubnetUsageCmdlet : PSCmdlet
public class GetSubnetUsageCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByCIDR")]
ParameterSetName = "ByCIDR",
HelpMessage = "The subnet in CIDR notation.")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string? CIDR { get; set; }
@@ -24,43 +27,60 @@ public class GetSubnetUsageCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The subnet ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "BySubnetObject",
HelpMessage = "The subnet object.")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
protected override void ProcessRecord()
{
try
{
int subnetId;
if (ParameterSetName == "ByCIDR")
{
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR! })
.GetAwaiter().GetResult();
if (subnet == null)
{
throw new Exception("Cannot find subnet!");
}
var subnetObj = subnet as Subnetwork;
subnetId = subnetObj!.Id;
}
else
{
subnetId = Id!.Value;
}
var subnetId = GetSubnetId();
var identifiers = new List<string> { subnetId.ToString(), "usage" };
var result = RequestHelper.InvokeRequest("GET", controllers.subnets, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (result != null)
{
WriteObject(result);
}
var result = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, null, null, null, identifiers.ToArray()
).GetAwaiter().GetResult();
WriteResult(result);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "GetSubnetUsageError", ErrorCategory.InvalidOperation, null));
}
}
private int GetSubnetId()
{
switch (ParameterSetName)
{
case "ByCIDR":
var subnet = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
new[] { "cidr", CIDR! }
).GetAwaiter().GetResult() as Subnetwork;
if (subnet == null)
{
throw new ItemNotFoundException($"Subnet '{CIDR}' not found.");
}
return subnet.Id;
case "BySubnetObject":
return SubnetObject!.Id;
default:
return Id!.Value;
}
}
}

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves tag information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Tag", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Tag))]
public class GetTagCmdlet : PSCmdlet
public class GetTagCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The tag ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -23,7 +27,8 @@ public class GetTagCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByAddressObject")]
ParameterSetName = "ByAddressObject",
HelpMessage = "Get the tag associated with this address.")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
@@ -32,7 +37,8 @@ public class GetTagCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
ParameterSetName = "BySubnetObject",
HelpMessage = "Get the tag associated with this subnet.")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
@@ -50,6 +56,7 @@ public class GetTagCmdlet : PSCmdlet
identifiers.Add(Id.Value.ToString());
}
break;
case "ByAddressObject":
if (AddressObject?.TagId > 0)
{
@@ -60,6 +67,7 @@ public class GetTagCmdlet : PSCmdlet
return;
}
break;
case "BySubnetObject":
if (SubnetObject?.TagId > 0)
{
@@ -72,23 +80,11 @@ public class GetTagCmdlet : PSCmdlet
break;
}
var result = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Tag, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", ApiController.Addresses, ModelType.Tag, null, null, identifiers.ToArray()
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves VLAN information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Vlan", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Vlan))]
public class GetVlanCmdlet : PSCmdlet
public class GetVlanCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The VLAN ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -23,7 +27,8 @@ public class GetVlanCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByNumber")]
ParameterSetName = "ByNumber",
HelpMessage = "The VLAN number.")]
[ValidateNotNullOrEmpty]
public int? Number { get; set; }
@@ -32,7 +37,8 @@ public class GetVlanCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByL2Domain")]
ParameterSetName = "ByL2Domain",
HelpMessage = "The L2 domain ID to get VLANs from.")]
[ValidateNotNullOrEmpty]
public int? L2DomainId { get; set; }
@@ -41,7 +47,8 @@ public class GetVlanCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
ParameterSetName = "BySubnetObject",
HelpMessage = "Get the VLAN associated with this subnet.")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
@@ -50,7 +57,8 @@ public class GetVlanCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByDomainObject")]
ParameterSetName = "ByDomainObject",
HelpMessage = "Get VLANs in this L2 domain.")]
[ValidateNotNullOrEmpty]
public Domain? DomainObject { get; set; }
@@ -58,7 +66,7 @@ public class GetVlanCmdlet : PSCmdlet
{
try
{
var controller = controllers.vlan;
var controller = ApiController.Vlan;
var identifiers = new List<string>();
switch (ParameterSetName)
@@ -66,65 +74,44 @@ public class GetVlanCmdlet : PSCmdlet
case "ByID":
identifiers.Add(Id!.Value.ToString());
break;
case "ByNumber":
identifiers.Add("search");
identifiers.Add(Number!.Value.ToString());
break;
case "ByL2Domain":
controller = controllers.l2domains;
controller = ApiController.L2Domains;
identifiers.Add(L2DomainId!.Value.ToString());
identifiers.Add(subcontrollers.vlans.ToString());
identifiers.Add(ApiSubController.Vlans.ToString().ToLowerInvariant());
break;
case "BySubnetObject":
if (SubnetObject != null && SubnetObject.VlanId > 0)
{
identifiers.Add(SubnetObject.VlanId.ToString());
}
else
if (SubnetObject == null || SubnetObject.VlanId <= 0)
{
return;
}
identifiers.Add(SubnetObject.VlanId.ToString());
break;
case "ByDomainObject":
if (DomainObject != null)
{
var result = RequestHelper.InvokeRequest("GET", controllers.l2domains, types.Vlan, subcontrollers.vlans, null, new[] { DomainObject.Id.ToString() })
.GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
var result = RequestHelper.InvokeRequest(
"GET", ApiController.L2Domains, ModelType.Vlan, ApiSubController.Vlans,
null, new[] { DomainObject.Id.ToString() }
).GetAwaiter().GetResult();
WriteResult(result);
}
return;
}
var vlanResult = RequestHelper.InvokeRequest("GET", controller, types.Vlan, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
var vlanResult = RequestHelper.InvokeRequest(
"GET", controller, ModelType.Vlan, null, null,
identifiers.Count > 0 ? identifiers.ToArray() : null
).GetAwaiter().GetResult();
if (vlanResult != null)
{
if (vlanResult is System.Collections.IEnumerable enumerable && !(vlanResult is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(vlanResult);
}
}
WriteResult(vlanResult);
}
catch (Exception ex)
{

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Retrieves VRF information from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Vrf", DefaultParameterSetName = "NoParams")]
[OutputType(typeof(Vrf))]
public class GetVrfCmdlet : PSCmdlet
public class GetVrfCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByID")]
ParameterSetName = "ByID",
HelpMessage = "The VRF ID.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -23,28 +27,18 @@ public class GetVrfCmdlet : PSCmdlet
try
{
var identifiers = new List<string>();
if (Id.HasValue)
{
identifiers.Add(Id.Value.ToString());
}
var result = RequestHelper.InvokeRequest("GET", controllers.vrf, types.Vrf, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"GET", ApiController.Vrf, ModelType.Vrf, null, null,
identifiers.Count > 0 ? identifiers.ToArray() : null
).GetAwaiter().GetResult();
if (result != null)
{
if (result is System.Collections.IEnumerable enumerable && !(result is string))
{
foreach (var item in enumerable)
{
WriteObject(item);
}
}
else
{
WriteObject(result);
}
}
WriteResult(result);
}
catch (Exception ex)
{

View File

@@ -1,21 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Creates a new IP address entry in phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.New, "Address", DefaultParameterSetName = "BySubnetId")]
[OutputType(typeof(Address))]
public class NewAddressCmdlet : PSCmdlet
public class NewAddressCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetId")]
ParameterSetName = "BySubnetId",
HelpMessage = "The subnet ID to create the address in.")]
[ValidateNotNullOrEmpty]
public int? SubnetId { get; set; }
@@ -24,7 +27,8 @@ public class NewAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "BySubnetObject")]
ParameterSetName = "BySubnetObject",
HelpMessage = "The subnet object to create the address in.")]
[ValidateNotNullOrEmpty]
public Subnetwork? SubnetObject { get; set; }
@@ -32,166 +36,73 @@ public class NewAddressCmdlet : PSCmdlet
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1)]
Position = 1,
HelpMessage = "The IP address to create.")]
[ValidateNotNullOrEmpty]
public string IP { get; set; } = string.Empty;
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2)]
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Mark this address as a gateway.")]
public SwitchParameter Gateway { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
[Parameter(Mandatory = false, Position = 3, HelpMessage = "Description for the address.")]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 4)]
[Parameter(Mandatory = false, Position = 4, HelpMessage = "Hostname for the address.")]
public string? Hostname { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 5)]
[Parameter(Mandatory = false, Position = 5, HelpMessage = "MAC address.")]
public string? MAC { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 6)]
[Parameter(Mandatory = false, Position = 6, HelpMessage = "Owner of the address.")]
public string? Owner { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
[Parameter(Mandatory = false, Position = 7, HelpMessage = "Tag ID for the address.")]
public int? TagId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 8)]
[Parameter(Mandatory = false, Position = 8, HelpMessage = "Ignore PTR record generation.")]
public SwitchParameter PTRIgnore { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
[Parameter(Mandatory = false, Position = 9, HelpMessage = "PTR record ID.")]
public int? PTRId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 10)]
[Parameter(Mandatory = false, Position = 10, HelpMessage = "Note for the address.")]
public string? Note { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 11)]
[Parameter(Mandatory = false, Position = 11, HelpMessage = "Exclude from ping scanning.")]
public SwitchParameter ExcludePing { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
[Parameter(Mandatory = false, Position = 12, HelpMessage = "Associated device ID.")]
public int? DeviceId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 13)]
[Parameter(Mandatory = false, Position = 13, HelpMessage = "Port information.")]
public string? Port { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 14)]
[Parameter(Mandatory = false, Position = 14, HelpMessage = "Custom fields as a hashtable or PSObject.")]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
int actualSubnetId;
if (ParameterSetName == "BySubnetObject")
{
actualSubnetId = SubnetObject!.Id;
}
else
{
actualSubnetId = SubnetId!.Value;
}
var actualSubnetId = ParameterSetName == "BySubnetObject"
? SubnetObject!.Id
: SubnetId!.Value;
var body = new Dictionary<string, object>
{
{ "subnetId", actualSubnetId },
{ "ip", IP }
};
var body = BuildRequestBody(actualSubnetId);
if (Gateway.IsPresent)
body["is_gateway"] = "1";
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname))
body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC))
body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner))
body["owner"] = Owner;
if (TagId.HasValue)
body["tag"] = TagId.Value;
if (PTRIgnore.IsPresent)
body["PTRignore"] = "1";
if (PTRId.HasValue)
body["PTR"] = PTRId.Value;
if (!string.IsNullOrEmpty(Note))
body["note"] = Note;
if (ExcludePing.IsPresent)
body["excludePing"] = "1";
if (DeviceId.HasValue)
body["deviceId"] = DeviceId.Value;
if (!string.IsNullOrEmpty(Port))
body["port"] = Port;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var result = RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, body, null)
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"POST", ApiController.Addresses, null, null, body
).GetAwaiter().GetResult();
if (result != null)
{
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "search", IP })
.GetAwaiter().GetResult();
if (address != null)
{
WriteObject(address);
}
// Fetch the created address to return it
var address = RequestHelper.InvokeRequest(
"GET", ApiController.Addresses, ModelType.Address, null, null,
new[] { "search", IP }
).GetAwaiter().GetResult();
WriteResult(address);
}
}
catch (Exception ex)
@@ -200,20 +111,32 @@ public class NewAddressCmdlet : PSCmdlet
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
private Dictionary<string, object> BuildRequestBody(int subnetId)
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
var body = new Dictionary<string, object>
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
["subnetId"] = subnetId,
["ip"] = IP
};
if (Gateway.IsPresent) body["is_gateway"] = "1";
if (!string.IsNullOrEmpty(Description)) body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname)) body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC)) body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner)) body["owner"] = Owner;
if (TagId.HasValue) body["tag"] = TagId.Value;
if (PTRIgnore.IsPresent) body["PTRignore"] = "1";
if (PTRId.HasValue) body["PTR"] = PTRId.Value;
if (!string.IsNullOrEmpty(Note)) body["note"] = Note;
if (ExcludePing.IsPresent) body["excludePing"] = "1";
if (DeviceId.HasValue) body["deviceId"] = DeviceId.Value;
if (!string.IsNullOrEmpty(Port)) body["port"] = Port;
foreach (var kvp in ConvertCustomFields(CustomFields))
{
return dictObj;
body[kvp.Key] = kvp.Value;
}
return dict;
return body;
}
}

View File

@@ -1,168 +1,85 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Creates a new address using the first available IP in a subnet.
/// </summary>
[Cmdlet(VerbsCommon.New, "FirstFreeIP")]
[OutputType(typeof(Address))]
public class NewFirstFreeIPCmdlet : PSCmdlet
public class NewFirstFreeIPCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
Position = 0,
HelpMessage = "The subnet ID to create the address in.")]
[ValidateNotNullOrEmpty]
public string SubnetId { get; set; } = string.Empty;
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2)]
[Parameter(Mandatory = false, Position = 1, HelpMessage = "Mark this address as a gateway.")]
public SwitchParameter Gateway { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Description for the address.")]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 4)]
[Parameter(Mandatory = false, Position = 3, HelpMessage = "Hostname for the address.")]
public string? Hostname { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 5)]
[Parameter(Mandatory = false, Position = 4, HelpMessage = "MAC address.")]
public string? MAC { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 6)]
[Parameter(Mandatory = false, Position = 5, HelpMessage = "Owner of the address.")]
public string? Owner { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
[Parameter(Mandatory = false, Position = 6, HelpMessage = "Tag ID for the address.")]
public string? TagId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 8)]
[Parameter(Mandatory = false, Position = 7, HelpMessage = "Ignore PTR record generation.")]
public SwitchParameter PTRIgnore { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 9)]
[Parameter(Mandatory = false, Position = 8, HelpMessage = "PTR record ID.")]
public string? PTRId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 10)]
[Parameter(Mandatory = false, Position = 9, HelpMessage = "Note for the address.")]
public string? Note { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 11)]
[Parameter(Mandatory = false, Position = 10, HelpMessage = "Exclude from ping scanning.")]
public SwitchParameter ExcludePing { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
[Parameter(Mandatory = false, Position = 11, HelpMessage = "Associated device ID.")]
public string? DeviceId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 13)]
[Parameter(Mandatory = false, Position = 12, HelpMessage = "Port information.")]
public string? Port { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[Parameter(Mandatory = false, HelpMessage = "Custom fields as a hashtable or PSObject.")]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string> { "first_free" };
var body = new Dictionary<string, object>
{
{ "subnetId", SubnetId }
};
var identifiers = new[] { "first_free" };
var body = BuildRequestBody();
if (Gateway.IsPresent)
body["is_gateway"] = "1";
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname))
body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC))
body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner))
body["owner"] = Owner;
if (!string.IsNullOrEmpty(TagId))
body["tag"] = TagId;
if (PTRIgnore.IsPresent)
body["PTRignore"] = "1";
if (!string.IsNullOrEmpty(PTRId))
body["PTR"] = PTRId;
if (!string.IsNullOrEmpty(Note))
body["note"] = Note;
if (ExcludePing.IsPresent)
body["excludePing"] = "1";
if (!string.IsNullOrEmpty(DeviceId))
body["deviceId"] = DeviceId;
if (!string.IsNullOrEmpty(Port))
body["port"] = Port;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var result = RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"POST", ApiController.Addresses, null, null, body, identifiers
).GetAwaiter().GetResult();
if (result != null)
{
var ip = result.ToString();
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "search", ip })
.GetAwaiter().GetResult();
if (address != null)
{
WriteObject(address);
}
var address = RequestHelper.InvokeRequest(
"GET", ApiController.Addresses, ModelType.Address, null, null,
new[] { "search", ip! }
).GetAwaiter().GetResult();
WriteResult(address);
}
}
catch (Exception ex)
@@ -171,20 +88,31 @@ public class NewFirstFreeIPCmdlet : PSCmdlet
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
private Dictionary<string, object> BuildRequestBody()
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
var body = new Dictionary<string, object>
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
["subnetId"] = SubnetId
};
if (Gateway.IsPresent) body["is_gateway"] = "1";
if (!string.IsNullOrEmpty(Description)) body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname)) body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC)) body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner)) body["owner"] = Owner;
if (!string.IsNullOrEmpty(TagId)) body["tag"] = TagId;
if (PTRIgnore.IsPresent) body["PTRignore"] = "1";
if (!string.IsNullOrEmpty(PTRId)) body["PTR"] = PTRId;
if (!string.IsNullOrEmpty(Note)) body["note"] = Note;
if (ExcludePing.IsPresent) body["excludePing"] = "1";
if (!string.IsNullOrEmpty(DeviceId)) body["deviceId"] = DeviceId;
if (!string.IsNullOrEmpty(Port)) body["port"] = Port;
foreach (var kvp in ConvertCustomFields(CustomFields))
{
return dictObj;
body[kvp.Key] = kvp.Value;
}
return dict;
return body;
}
}

View File

@@ -1,18 +1,22 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Management.Automation;
using System.Threading.Tasks;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Creates a new phpIPAM API session.
/// </summary>
[Cmdlet(VerbsCommon.New, "Session", DefaultParameterSetName = "Credentials")]
public class NewSessionCmdlet : PSCmdlet
[OutputType(typeof(Session))]
public class NewSessionCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
Position = 0,
HelpMessage = "The phpIPAM server URL (must start with http:// or https://).")]
[ValidateNotNullOrEmpty]
[ValidatePattern("^https?://")]
public string URL { get; set; } = string.Empty;
@@ -21,7 +25,8 @@ public class NewSessionCmdlet : PSCmdlet
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1)]
Position = 1,
HelpMessage = "The API application ID configured in phpIPAM.")]
[ValidateNotNullOrEmpty]
public string AppID { get; set; } = string.Empty;
@@ -30,7 +35,8 @@ public class NewSessionCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "Credentials")]
ParameterSetName = "Credentials",
HelpMessage = "The credentials (username and password) for authentication.")]
[ValidateNotNullOrEmpty]
public PSCredential? Credentials { get; set; }
@@ -39,7 +45,8 @@ public class NewSessionCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2,
ParameterSetName = "Token")]
ParameterSetName = "Token",
HelpMessage = "The static API token for authentication.")]
[ValidateNotNullOrEmpty]
public string? Token { get; set; }
@@ -47,7 +54,8 @@ public class NewSessionCmdlet : PSCmdlet
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
Position = 3,
HelpMessage = "If specified, SSL certificate errors will be ignored.")]
public SwitchParameter IgnoreSSL { get; set; }
protected override void ProcessRecord()
@@ -55,9 +63,10 @@ public class NewSessionCmdlet : PSCmdlet
try
{
Session session;
if (ParameterSetName == "Credentials" && Credentials != null)
{
session = SessionManager.CreateSessionWithCredentials(
session = SessionManager.CreateSessionWithCredentialsAsync(
URL,
AppID,
Credentials,
@@ -70,12 +79,14 @@ public class NewSessionCmdlet : PSCmdlet
}
else
{
throw new ArgumentException("Invalid parameter set");
throw new ArgumentException("Invalid parameter set. Provide either Credentials or Token.");
}
WriteObject(session);
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, "NewSessionError", ErrorCategory.InvalidOperation, null));
WriteError(new ErrorRecord(ex, "NewSessionError", ErrorCategory.AuthenticationError, null));
}
}
}

View File

@@ -1,20 +1,23 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Net;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Creates a new subnet in phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.New, "Subnet")]
[OutputType(typeof(Subnetwork))]
public class NewSubnetCmdlet : PSCmdlet
public class NewSubnetCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
Position = 0,
HelpMessage = "The subnet in CIDR notation (e.g., 192.168.1.0/24).")]
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
[ValidateNotNullOrEmpty]
public string CIDR { get; set; } = string.Empty;
@@ -23,187 +26,79 @@ public class NewSubnetCmdlet : PSCmdlet
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 1)]
Position = 1,
HelpMessage = "The section ID to create the subnet in.")]
[ValidateNotNullOrEmpty]
public int SectionId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 2)]
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Description for the subnet.")]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 3)]
[Parameter(Mandatory = false, Position = 3, HelpMessage = "VLAN ID to associate.")]
public int? VlanId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 4)]
[Parameter(Mandatory = false, Position = 4, HelpMessage = "VRF ID to associate.")]
public int? VrfId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 5)]
[Parameter(Mandatory = false, Position = 5, HelpMessage = "Master subnet ID for hierarchy.")]
public int? MasterSubnetId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 6)]
[Parameter(Mandatory = false, Position = 6, HelpMessage = "Nameserver ID.")]
public int? NameserverId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 7)]
[Parameter(Mandatory = false, Position = 7, HelpMessage = "Show subnet name.")]
public SwitchParameter ShowName { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 8)]
[Parameter(Mandatory = false, Position = 8, HelpMessage = "Enable recursive DNS.")]
public SwitchParameter DNSRecursive { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 9)]
[Parameter(Mandatory = false, Position = 9, HelpMessage = "Enable DNS records.")]
public SwitchParameter DNSRecords { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 10)]
[Parameter(Mandatory = false, Position = 10, HelpMessage = "Allow IP requests.")]
public SwitchParameter AllowRequests { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 11)]
[Parameter(Mandatory = false, Position = 11, HelpMessage = "Scan agent ID.")]
public int? ScanAgentId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
[Parameter(Mandatory = false, Position = 12, HelpMessage = "Enable subnet discovery.")]
public SwitchParameter DiscoverSubnet { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
[Parameter(Mandatory = false, Position = 13, HelpMessage = "Mark subnet as full.")]
public SwitchParameter IsFull { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 12)]
[Parameter(Mandatory = false, Position = 14, HelpMessage = "Tag ID for the subnet.")]
public int? TagId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 13)]
[Parameter(Mandatory = false, Position = 15, HelpMessage = "Usage threshold percentage (1-100).")]
[ValidateRange(1, 100)]
public int? Threshold { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 14)]
[Parameter(Mandatory = false, Position = 16, HelpMessage = "Location ID.")]
public int? LocationId { get; set; }
[Parameter(
Mandatory = false,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 15)]
[Parameter(Mandatory = false, HelpMessage = "Custom fields as a hashtable or PSObject.")]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
var parts = CIDR.Split('/');
var body = new Dictionary<string, object>
{
{ "subnet", parts[0] },
{ "mask", parts[1] },
{ "sectionId", SectionId }
};
var body = BuildRequestBody();
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (VlanId.HasValue)
body["vlanId"] = VlanId.Value;
if (VrfId.HasValue)
body["vrfId"] = VrfId.Value;
if (MasterSubnetId.HasValue)
body["masterSubnetId"] = MasterSubnetId.Value;
if (NameserverId.HasValue)
body["nameserverId"] = NameserverId.Value;
if (ShowName.IsPresent)
body["showName"] = "1";
if (DNSRecursive.IsPresent)
body["DNSrecursive"] = "1";
if (DNSRecords.IsPresent)
body["DNSrecords"] = "1";
if (AllowRequests.IsPresent)
body["allowRequests"] = "1";
if (ScanAgentId.HasValue)
body["scanAgent"] = ScanAgentId.Value;
if (DiscoverSubnet.IsPresent)
body["discoverSubnet"] = "1";
if (IsFull.IsPresent)
body["isFull"] = "1";
if (TagId.HasValue)
body["state"] = TagId.Value;
if (Threshold.HasValue)
body["threshold"] = Threshold.Value;
if (LocationId.HasValue)
body["location"] = LocationId.Value;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var result = RequestHelper.InvokeRequest("POST", controllers.subnets, null, null, body, null)
.GetAwaiter().GetResult();
var result = RequestHelper.InvokeRequest(
"POST", ApiController.Subnets, null, null, body
).GetAwaiter().GetResult();
if (result != null)
{
// Get the created subnet
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR })
.GetAwaiter().GetResult();
if (subnet != null)
{
WriteObject(subnet);
}
var subnet = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
new[] { "cidr", CIDR }
).GetAwaiter().GetResult();
WriteResult(subnet);
}
}
catch (Exception ex)
@@ -212,20 +107,37 @@ public class NewSubnetCmdlet : PSCmdlet
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
private Dictionary<string, object> BuildRequestBody()
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
var parts = CIDR.Split('/');
var body = new Dictionary<string, object>
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
}
else if (customFields is Dictionary<string, object> dictObj)
["subnet"] = parts[0],
["mask"] = parts[1],
["sectionId"] = SectionId
};
if (!string.IsNullOrEmpty(Description)) body["description"] = Description;
if (VlanId.HasValue) body["vlanId"] = VlanId.Value;
if (VrfId.HasValue) body["vrfId"] = VrfId.Value;
if (MasterSubnetId.HasValue) body["masterSubnetId"] = MasterSubnetId.Value;
if (NameserverId.HasValue) body["nameserverId"] = NameserverId.Value;
if (ShowName.IsPresent) body["showName"] = "1";
if (DNSRecursive.IsPresent) body["DNSrecursive"] = "1";
if (DNSRecords.IsPresent) body["DNSrecords"] = "1";
if (AllowRequests.IsPresent) body["allowRequests"] = "1";
if (ScanAgentId.HasValue) body["scanAgent"] = ScanAgentId.Value;
if (DiscoverSubnet.IsPresent) body["discoverSubnet"] = "1";
if (IsFull.IsPresent) body["isFull"] = "1";
if (TagId.HasValue) body["state"] = TagId.Value;
if (Threshold.HasValue) body["threshold"] = Threshold.Value;
if (LocationId.HasValue) body["location"] = LocationId.Value;
foreach (var kvp in ConvertCustomFields(CustomFields))
{
return dictObj;
body[kvp.Key] = kvp.Value;
}
return dict;
return body;
}
}

View File

@@ -1,27 +1,31 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
[Cmdlet(VerbsCommon.Remove, "Address", DefaultParameterSetName = "ByID")]
public class RemoveAddressCmdlet : PSCmdlet
/// <summary>
/// Removes an IP address entry from phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Remove, "Address", DefaultParameterSetName = "ById", SupportsShouldProcess = true)]
public class RemoveAddressCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByID")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByAddressObject")]
ParameterSetName = "ById",
HelpMessage = "The address ID to remove.")]
[ValidateNotNullOrEmpty]
public int Id { get; set; }
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
Position = 0,
ParameterSetName = "ByAddressObject",
HelpMessage = "The address object to remove.")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
@@ -29,19 +33,17 @@ public class RemoveAddressCmdlet : PSCmdlet
{
try
{
int addressId;
if (ParameterSetName == "ByID")
{
addressId = Id!.Value;
}
else
{
addressId = AddressObject!.Id;
}
var addressId = ParameterSetName == "ById" ? Id : AddressObject!.Id;
var identifiers = new[] { addressId.ToString() };
var identifiers = new List<string> { addressId.ToString() };
RequestHelper.InvokeRequest("DELETE", controllers.addresses, null, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (ShouldProcess($"Address ID: {addressId}", "Remove"))
{
RequestHelper.InvokeRequest(
"DELETE", ApiController.Addresses, null, null, null, identifiers
).GetAwaiter().GetResult();
WriteVerbose($"Address {addressId} removed successfully.");
}
}
catch (Exception ex)
{

View File

@@ -1,20 +1,24 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Updates an existing IP address entry in phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Set, "Address", DefaultParameterSetName = "ById")]
[OutputType(typeof(Address))]
public class SetAddressCmdlet : PSCmdlet
public class SetAddressCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ById")]
ParameterSetName = "ById",
HelpMessage = "The address ID to update.")]
[ValidateNotNullOrEmpty]
public int? Id { get; set; }
@@ -23,142 +27,72 @@ public class SetAddressCmdlet : PSCmdlet
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0,
ParameterSetName = "ByAddressObject")]
ParameterSetName = "ByAddressObject",
HelpMessage = "The address object to update.")]
[ValidateNotNullOrEmpty]
public Address? AddressObject { get; set; }
[Parameter(
Position = 1,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "ById")]
[Parameter(Position = 1, HelpMessage = "Set as gateway address.")]
public bool? Gateway { get; set; }
[Parameter(
Position = 2,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "ById")]
[Parameter(Position = 2, HelpMessage = "Description for the address.")]
public string? Description { get; set; }
[Parameter(
Mandatory = false,
Position = 3)]
[Parameter(Position = 3, HelpMessage = "Hostname for the address.")]
public string? Hostname { get; set; }
[Parameter(
Mandatory = false,
Position = 4)]
[Parameter(Position = 4, HelpMessage = "MAC address.")]
public string? MAC { get; set; }
[Parameter(
Mandatory = false,
Position = 5)]
[Parameter(Position = 5, HelpMessage = "Owner of the address.")]
public string? Owner { get; set; }
[Parameter(
Mandatory = false,
Position = 6)]
[Parameter(Position = 6, HelpMessage = "Tag ID for the address.")]
public int? TagId { get; set; }
[Parameter(
Mandatory = false,
Position = 7)]
[Parameter(Position = 7, HelpMessage = "Ignore PTR record generation.")]
public bool? PTRIgnore { get; set; }
[Parameter(
Mandatory = false,
Position = 8)]
[Parameter(Position = 8, HelpMessage = "PTR record ID.")]
public int? PTRId { get; set; }
[Parameter(
Mandatory = false,
Position = 9)]
[Parameter(Position = 9, HelpMessage = "Note for the address.")]
public string? Note { get; set; }
[Parameter(
Mandatory = false,
Position = 10)]
[Parameter(Position = 10, HelpMessage = "Exclude from ping scanning.")]
public bool? ExcludePing { get; set; }
[Parameter(
Mandatory = false,
Position = 11)]
[Parameter(Position = 11, HelpMessage = "Associated device ID.")]
public int? DeviceId { get; set; }
[Parameter(
Mandatory = false,
Position = 12)]
[Parameter(Position = 12, HelpMessage = "Port information.")]
public string? Port { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(HelpMessage = "Custom fields as a hashtable or PSObject.")]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
int addressId;
if (ParameterSetName == "ById")
{
addressId = Id!.Value;
}
else
{
addressId = AddressObject!.Id;
}
var identifiers = new List<string> { addressId.ToString() };
var body = new Dictionary<string, object>();
if (Gateway.HasValue)
body["is_gateway"] = Gateway.Value;
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname))
body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC))
body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner))
body["owner"] = Owner;
if (TagId.HasValue)
body["tag"] = TagId.Value;
if (PTRIgnore.HasValue)
body["PTRignore"] = PTRIgnore.Value;
if (PTRId.HasValue)
body["PTR"] = PTRId.Value;
if (!string.IsNullOrEmpty(Note))
body["note"] = Note;
if (ExcludePing.HasValue)
body["excludePing"] = ExcludePing.Value;
if (DeviceId.HasValue)
body["deviceId"] = DeviceId.Value;
if (!string.IsNullOrEmpty(Port))
body["port"] = Port;
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var addressId = ParameterSetName == "ById" ? Id!.Value : AddressObject!.Id;
var identifiers = new[] { addressId.ToString() };
var body = BuildRequestBody();
try
{
RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
RequestHelper.InvokeRequest(
"PATCH", ApiController.Addresses, null, null, body, identifiers
).GetAwaiter().GetResult();
}
finally
{
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (address != null)
{
WriteObject(address);
}
// Always return the updated address
var address = RequestHelper.InvokeRequest(
"GET", ApiController.Addresses, ModelType.Address, null, null, identifiers
).GetAwaiter().GetResult();
WriteResult(address);
}
}
catch (Exception ex)
@@ -167,20 +101,28 @@ public class SetAddressCmdlet : PSCmdlet
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
private Dictionary<string, object> BuildRequestBody()
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
var body = new Dictionary<string, object>();
if (Gateway.HasValue) body["is_gateway"] = Gateway.Value;
if (!string.IsNullOrEmpty(Description)) body["description"] = Description;
if (!string.IsNullOrEmpty(Hostname)) body["hostname"] = Hostname;
if (!string.IsNullOrEmpty(MAC)) body["mac"] = MAC;
if (!string.IsNullOrEmpty(Owner)) body["owner"] = Owner;
if (TagId.HasValue) body["tag"] = TagId.Value;
if (PTRIgnore.HasValue) body["PTRignore"] = PTRIgnore.Value;
if (PTRId.HasValue) body["PTR"] = PTRId.Value;
if (!string.IsNullOrEmpty(Note)) body["note"] = Note;
if (ExcludePing.HasValue) body["excludePing"] = ExcludePing.Value;
if (DeviceId.HasValue) body["deviceId"] = DeviceId.Value;
if (!string.IsNullOrEmpty(Port)) body["port"] = Port;
foreach (var kvp in ConvertCustomFields(CustomFields))
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
body[kvp.Key] = kvp.Value;
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
return body;
}
}

View File

@@ -1,143 +1,91 @@
namespace PS.IPAM.Cmdlets;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using PS.IPAM;
using PS.IPAM.Helpers;
/// <summary>
/// Updates an existing subnet in phpIPAM.
/// </summary>
[Cmdlet(VerbsCommon.Set, "Subnet")]
[OutputType(typeof(Subnetwork))]
public class SetSubnetCmdlet : PSCmdlet
public class SetSubnetCmdlet : BaseCmdlet
{
[Parameter(
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
Position = 0)]
Position = 0,
HelpMessage = "The subnet ID to update.")]
[ValidateNotNullOrEmpty]
public int Id { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Description for the subnet.")]
public string? Description { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "VLAN ID to associate.")]
public int? VlanId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "VRF ID to associate.")]
public int? VrfId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Master subnet ID for hierarchy.")]
public int? MasterSubnetId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Nameserver ID.")]
public int? NameserverId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Show subnet name.")]
public SwitchParameter ShowName { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Enable recursive DNS.")]
public SwitchParameter DNSRecursive { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Enable DNS records.")]
public SwitchParameter DNSRecords { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Allow IP requests.")]
public SwitchParameter AllowRequests { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Scan agent ID.")]
public int? ScanAgentId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Enable subnet discovery.")]
public SwitchParameter DiscoverSubnet { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Mark subnet as full.")]
public SwitchParameter IsFull { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Tag ID for the subnet.")]
public int? TagId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Usage threshold percentage (1-100).")]
[ValidateRange(1, 100)]
public int? Threshold { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Location ID.")]
public int? LocationId { get; set; }
[Parameter(
Mandatory = false)]
[Parameter(Mandatory = false, HelpMessage = "Custom fields as a hashtable or PSObject.")]
public object? CustomFields { get; set; }
protected override void ProcessRecord()
{
try
{
var identifiers = new List<string> { Id.ToString() };
var body = new Dictionary<string, object>();
var identifiers = new[] { Id.ToString() };
var body = BuildRequestBody();
if (!string.IsNullOrEmpty(Description))
body["description"] = Description;
if (VlanId.HasValue)
body["vlanId"] = VlanId.Value;
if (VrfId.HasValue)
body["vrfId"] = VrfId.Value;
if (MasterSubnetId.HasValue)
body["masterSubnetId"] = MasterSubnetId.Value;
if (NameserverId.HasValue)
body["nameserverId"] = NameserverId.Value;
if (ShowName.IsPresent)
body["showName"] = "1";
if (DNSRecursive.IsPresent)
body["DNSrecursive"] = "1";
if (DNSRecords.IsPresent)
body["DNSrecords"] = "1";
if (AllowRequests.IsPresent)
body["allowRequests"] = "1";
if (ScanAgentId.HasValue)
body["scanAgent"] = ScanAgentId.Value;
if (DiscoverSubnet.IsPresent)
body["discoverSubnet"] = "1";
if (IsFull.IsPresent)
body["isFull"] = "1";
if (TagId.HasValue)
body["state"] = TagId.Value;
if (Threshold.HasValue)
body["threshold"] = Threshold.Value;
if (LocationId.HasValue)
body["location"] = LocationId.Value;
RequestHelper.InvokeRequest(
"PATCH", ApiController.Subnets, null, null, body, identifiers
).GetAwaiter().GetResult();
if (CustomFields != null)
{
var customDict = ConvertCustomFields(CustomFields);
foreach (var kvp in customDict)
{
body[kvp.Key] = kvp.Value;
}
}
var subnet = RequestHelper.InvokeRequest(
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null, identifiers
).GetAwaiter().GetResult();
RequestHelper.InvokeRequest("PATCH", controllers.subnets, null, null, body, identifiers.ToArray())
.GetAwaiter().GetResult();
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, identifiers.ToArray())
.GetAwaiter().GetResult();
if (subnet != null)
{
WriteObject(subnet);
}
WriteResult(subnet);
}
catch (Exception ex)
{
@@ -145,20 +93,31 @@ public class SetSubnetCmdlet : PSCmdlet
}
}
private Dictionary<string, object> ConvertCustomFields(object customFields)
private Dictionary<string, object> BuildRequestBody()
{
var dict = new Dictionary<string, object>();
if (customFields is PSObject psobj)
var body = new Dictionary<string, object>();
if (!string.IsNullOrEmpty(Description)) body["description"] = Description;
if (VlanId.HasValue) body["vlanId"] = VlanId.Value;
if (VrfId.HasValue) body["vrfId"] = VrfId.Value;
if (MasterSubnetId.HasValue) body["masterSubnetId"] = MasterSubnetId.Value;
if (NameserverId.HasValue) body["nameserverId"] = NameserverId.Value;
if (ShowName.IsPresent) body["showName"] = "1";
if (DNSRecursive.IsPresent) body["DNSrecursive"] = "1";
if (DNSRecords.IsPresent) body["DNSrecords"] = "1";
if (AllowRequests.IsPresent) body["allowRequests"] = "1";
if (ScanAgentId.HasValue) body["scanAgent"] = ScanAgentId.Value;
if (DiscoverSubnet.IsPresent) body["discoverSubnet"] = "1";
if (IsFull.IsPresent) body["isFull"] = "1";
if (TagId.HasValue) body["state"] = TagId.Value;
if (Threshold.HasValue) body["threshold"] = Threshold.Value;
if (LocationId.HasValue) body["location"] = LocationId.Value;
foreach (var kvp in ConvertCustomFields(CustomFields))
{
foreach (var prop in psobj.Properties)
{
dict[prop.Name] = prop.Value ?? new object();
}
body[kvp.Key] = kvp.Value;
}
else if (customFields is Dictionary<string, object> dictObj)
{
return dictObj;
}
return dict;
return body;
}
}