278 lines
8.6 KiB
C#
278 lines
8.6 KiB
C#
namespace PS.IPAM.Cmdlets;
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Management.Automation;
|
|
using PS.IPAM.Helpers;
|
|
|
|
/// <summary>
|
|
/// Retrieves subnet information from phpIPAM.
|
|
/// </summary>
|
|
[Cmdlet(VerbsCommon.Get, "Subnet", DefaultParameterSetName = "NoParams")]
|
|
[OutputType(typeof(Subnetwork))]
|
|
public class GetSubnetCmdlet : BaseCmdlet
|
|
{
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
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; }
|
|
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
ParameterSetName = "ByID",
|
|
HelpMessage = "The subnet ID.")]
|
|
[ValidateNotNullOrEmpty]
|
|
public int? Id { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
ParameterSetName = "BySectionId",
|
|
HelpMessage = "The section ID to get subnets from.")]
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 2,
|
|
ParameterSetName = "ByVlanNumber")]
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 1,
|
|
ParameterSetName = "ByVlanId")]
|
|
[ValidateNotNullOrEmpty]
|
|
public int? SectionId { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
ParameterSetName = "BySectionName",
|
|
HelpMessage = "The section name to get subnets from.")]
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 3,
|
|
ParameterSetName = "ByVlanNumber")]
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 2,
|
|
ParameterSetName = "ByVlanId")]
|
|
[ValidateNotNullOrEmpty]
|
|
public string? SectionName { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
ParameterSetName = "ByVrfId",
|
|
HelpMessage = "The VRF ID to get subnets from.")]
|
|
[ValidateNotNullOrEmpty]
|
|
public int? VrfId { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
ParameterSetName = "ByVlanId",
|
|
HelpMessage = "The VLAN ID to get subnets from.")]
|
|
[ValidateNotNullOrEmpty]
|
|
public int? VlanId { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = true,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 0,
|
|
ParameterSetName = "ByVlanNumber",
|
|
HelpMessage = "The VLAN number to get subnets from.")]
|
|
[ValidateNotNullOrEmpty]
|
|
public int? VlanNumber { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 1,
|
|
ParameterSetName = "ByID",
|
|
HelpMessage = "Get child subnets (slaves).")]
|
|
public SwitchParameter Slaves { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 2,
|
|
ParameterSetName = "ByID",
|
|
HelpMessage = "Get child subnets recursively.")]
|
|
public SwitchParameter Recurse { get; set; }
|
|
|
|
[Parameter(
|
|
Mandatory = false,
|
|
ValueFromPipeline = true,
|
|
ValueFromPipelineByPropertyName = true,
|
|
Position = 1,
|
|
ParameterSetName = "ByVlanNumber",
|
|
HelpMessage = "The L2 domain ID to narrow VLAN search.")]
|
|
[ValidateNotNullOrEmpty]
|
|
public int? VlanDomainId { get; set; }
|
|
|
|
protected override void ProcessRecord()
|
|
{
|
|
try
|
|
{
|
|
var controller = ApiController.Subnets;
|
|
var identifiers = new List<string>();
|
|
|
|
switch (ParameterSetName)
|
|
{
|
|
case "ByCIDR":
|
|
identifiers.Add("cidr");
|
|
identifiers.Add(CIDR!);
|
|
break;
|
|
|
|
case "ByID":
|
|
identifiers.Add(Id!.Value.ToString());
|
|
if (Slaves.IsPresent)
|
|
{
|
|
identifiers.Add(Recurse.IsPresent ? "slaves_recursive" : "slaves");
|
|
}
|
|
break;
|
|
|
|
case "BySectionId":
|
|
controller = ApiController.Sections;
|
|
identifiers.Add(SectionId!.Value.ToString());
|
|
identifiers.Add("subnets");
|
|
break;
|
|
|
|
case "BySectionName":
|
|
controller = ApiController.Sections;
|
|
var section = GetSectionByName(SectionName!);
|
|
identifiers.Add(section.Id.ToString());
|
|
identifiers.Add("subnets");
|
|
break;
|
|
|
|
case "ByVrfId":
|
|
controller = ApiController.Vrf;
|
|
identifiers.Add(VrfId!.Value.ToString());
|
|
identifiers.Add("subnets");
|
|
break;
|
|
|
|
case "ByVlanId":
|
|
controller = ApiController.Vlan;
|
|
identifiers.Add(VlanId!.Value.ToString());
|
|
identifiers.Add("subnets");
|
|
AddSectionIdentifier(identifiers);
|
|
break;
|
|
|
|
case "ByVlanNumber":
|
|
controller = ApiController.Vlan;
|
|
var vlan = FindVlanByNumber(VlanNumber!.Value, VlanDomainId);
|
|
identifiers.Add(vlan.Id.ToString());
|
|
identifiers.Add("subnets");
|
|
AddSectionIdentifier(identifiers);
|
|
break;
|
|
}
|
|
|
|
var result = RequestHelper.InvokeRequest(
|
|
"GET", controller, ModelType.Subnetwork, null, null, identifiers.ToArray()
|
|
).GetAwaiter().GetResult();
|
|
|
|
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());
|
|
}
|
|
}
|
|
}
|