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:
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user