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:
@@ -109,6 +109,13 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
cmdlet.SubnetCIDR.Should().Be("192.168.1.0/24");
|
cmdlet.SubnetCIDR.Should().Be("192.168.1.0/24");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetAddressCmdlet_InheritsFromBaseCmdlet()
|
||||||
|
{
|
||||||
|
var cmdlet = new GetAddressCmdlet();
|
||||||
|
cmdlet.Should().BeAssignableTo<BaseCmdlet>();
|
||||||
|
}
|
||||||
|
|
||||||
// Test the underlying RequestHelper functionality that the cmdlet uses
|
// Test the underlying RequestHelper functionality that the cmdlet uses
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -129,8 +136,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest(
|
var result = await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "1" }
|
new[] { "1" }
|
||||||
@@ -155,8 +162,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest(
|
await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "42" }
|
new[] { "42" }
|
||||||
@@ -177,8 +184,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest(
|
await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "search", "192.168.1.50" }
|
new[] { "search", "192.168.1.50" }
|
||||||
@@ -199,8 +206,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest(
|
await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "search_hostname", "myserver.example.com" }
|
new[] { "search_hostname", "myserver.example.com" }
|
||||||
@@ -221,8 +228,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest(
|
await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.subnets,
|
ApiController.Subnets,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "10", "addresses" }
|
new[] { "10", "addresses" }
|
||||||
@@ -243,8 +250,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest(
|
await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "tags", "2", "addresses" }
|
new[] { "tags", "2", "addresses" }
|
||||||
@@ -269,8 +276,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest(
|
var result = await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.subnets,
|
ApiController.Subnets,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "10", "addresses" }
|
new[] { "10", "addresses" }
|
||||||
@@ -294,8 +301,8 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest(
|
var result = await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address,
|
ModelType.Address,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
new[] { "999" }
|
new[] { "999" }
|
||||||
@@ -313,11 +320,11 @@ public class GetAddressCmdletTests : IDisposable
|
|||||||
// Act
|
// Act
|
||||||
var action = async () => await RequestHelper.InvokeRequest(
|
var action = async () => await RequestHelper.InvokeRequest(
|
||||||
"GET",
|
"GET",
|
||||||
controllers.addresses,
|
ApiController.Addresses,
|
||||||
types.Address
|
ModelType.Address
|
||||||
);
|
);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await action.Should().ThrowAsync<Exception>().WithMessage("No session available!");
|
await action.Should().ThrowAsync<InvalidOperationException>().WithMessage("No session available!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,11 +93,18 @@ public class NewSessionCmdletTests : IDisposable
|
|||||||
session.URL.Should().Be("https://ipam.example.com");
|
session.URL.Should().Be("https://ipam.example.com");
|
||||||
session.AppID.Should().Be("testapp");
|
session.AppID.Should().Be("testapp");
|
||||||
session.Token.Should().Be("my-api-token");
|
session.Token.Should().Be("my-api-token");
|
||||||
session.AuthType.Should().Be(AuthType.token);
|
session.AuthType.Should().Be(AuthType.Token);
|
||||||
session.Expires.Should().BeNull();
|
session.Expires.Should().BeNull();
|
||||||
session.Credentials.Should().BeNull();
|
session.Credentials.Should().BeNull();
|
||||||
|
|
||||||
// Verify it was set as current session
|
// Verify it was set as current session
|
||||||
SessionManager.CurrentSession.Should().BeSameAs(session);
|
SessionManager.CurrentSession.Should().BeSameAs(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NewSessionCmdlet_InheritsFromBaseCmdlet()
|
||||||
|
{
|
||||||
|
var cmdlet = new NewSessionCmdlet();
|
||||||
|
cmdlet.Should().BeAssignableTo<BaseCmdlet>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ public class RequestHelperTests : IDisposable
|
|||||||
_mockHandler?.ForceDispose();
|
_mockHandler?.ForceDispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupSession(AuthType authType = AuthType.token)
|
private void SetupSession(AuthType authType = AuthType.Token)
|
||||||
{
|
{
|
||||||
if (authType == AuthType.token)
|
if (authType == AuthType.Token)
|
||||||
{
|
{
|
||||||
SessionManager.CreateSessionWithToken("https://ipam.example.com", "testapp", "test-token");
|
SessionManager.CreateSessionWithToken("https://ipam.example.com", "testapp", "test-token");
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
{
|
{
|
||||||
// For credentials auth, we need to set up a session manually with future expiry
|
// For credentials auth, we need to set up a session manually with future expiry
|
||||||
var session = new Session(
|
var session = new Session(
|
||||||
AuthType.credentials,
|
AuthType.Credentials,
|
||||||
"cred-token",
|
"cred-token",
|
||||||
"testapp",
|
"testapp",
|
||||||
"https://ipam.example.com",
|
"https://ipam.example.com",
|
||||||
@@ -61,10 +61,10 @@ public class RequestHelperTests : IDisposable
|
|||||||
// Arrange - no session set up
|
// Arrange - no session set up
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var action = async () => await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
var action = async () => await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await action.Should().ThrowAsync<Exception>().WithMessage("No session available!");
|
await action.Should().ThrowAsync<InvalidOperationException>().WithMessage("No session available!");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -76,7 +76,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("{\"id\":1,\"ip\":\"192.168.1.1\"}");
|
handler.WithSuccessResponse("{\"id\":1,\"ip\":\"192.168.1.1\"}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
await RequestHelper.InvokeRequest("GET", ApiController.Addresses, ModelType.Address, null, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest.Should().NotBeNull();
|
handler.LastRequest.Should().NotBeNull();
|
||||||
@@ -92,7 +92,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("[]");
|
handler.WithSuccessResponse("[]");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("GET", controllers.subnets, null, subcontrollers.tags, null, new[] { "1" });
|
await RequestHelper.InvokeRequest("GET", ApiController.Subnets, null, ApiSubController.Tags, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.RequestUri!.ToString().Should().Contain("/subnets/tags/1/");
|
handler.LastRequest!.RequestUri!.ToString().Should().Contain("/subnets/tags/1/");
|
||||||
@@ -102,12 +102,12 @@ public class RequestHelperTests : IDisposable
|
|||||||
public async Task InvokeRequest_WithTokenAuth_AddsPhpipamTokenHeader()
|
public async Task InvokeRequest_WithTokenAuth_AddsPhpipamTokenHeader()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
SetupSession(AuthType.token);
|
SetupSession(AuthType.Token);
|
||||||
var handler = SetupMockHandler();
|
var handler = SetupMockHandler();
|
||||||
handler.WithSuccessResponse("{}");
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.GetLastRequestHeader("phpipam-token").Should().Be("test-token");
|
handler.GetLastRequestHeader("phpipam-token").Should().Be("test-token");
|
||||||
@@ -117,12 +117,12 @@ public class RequestHelperTests : IDisposable
|
|||||||
public async Task InvokeRequest_WithCredentialsAuth_AddsTokenHeader()
|
public async Task InvokeRequest_WithCredentialsAuth_AddsTokenHeader()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
SetupSession(AuthType.credentials);
|
SetupSession(AuthType.Credentials);
|
||||||
var handler = SetupMockHandler();
|
var handler = SetupMockHandler();
|
||||||
handler.WithSuccessResponse("{}");
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.GetLastRequestHeader("token").Should().Be("cred-token");
|
handler.GetLastRequestHeader("token").Should().Be("cred-token");
|
||||||
@@ -137,7 +137,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("{}");
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.Method.Should().Be(HttpMethod.Get);
|
handler.LastRequest!.Method.Should().Be(HttpMethod.Get);
|
||||||
@@ -152,7 +152,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("{\"id\":1}");
|
handler.WithSuccessResponse("{\"id\":1}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, new { ip = "10.0.0.1" });
|
await RequestHelper.InvokeRequest("POST", ApiController.Addresses, null, null, new { ip = "10.0.0.1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.Method.Should().Be(HttpMethod.Post);
|
handler.LastRequest!.Method.Should().Be(HttpMethod.Post);
|
||||||
@@ -167,7 +167,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("{\"id\":1}");
|
handler.WithSuccessResponse("{\"id\":1}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, new { description = "updated" }, new[] { "1" });
|
await RequestHelper.InvokeRequest("PATCH", ApiController.Addresses, null, null, new { description = "updated" }, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.Method.Should().Be(new HttpMethod("PATCH"));
|
handler.LastRequest!.Method.Should().Be(new HttpMethod("PATCH"));
|
||||||
@@ -182,7 +182,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("{}");
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("DELETE", controllers.addresses, null, null, null, new[] { "1" });
|
await RequestHelper.InvokeRequest("DELETE", ApiController.Addresses, null, null, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.Method.Should().Be(HttpMethod.Delete);
|
handler.LastRequest!.Method.Should().Be(HttpMethod.Delete);
|
||||||
@@ -197,7 +197,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithNotFoundResponse();
|
handler.WithNotFoundResponse();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "999" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Addresses, ModelType.Address, null, null, new[] { "999" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeNull();
|
result.Should().BeNull();
|
||||||
@@ -212,7 +212,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithErrorResponse(HttpStatusCode.InternalServerError, "Server error");
|
handler.WithErrorResponse(HttpStatusCode.InternalServerError, "Server error");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var action = async () => await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
var action = async () => await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
await action.Should().ThrowAsync<HttpRequestException>();
|
await action.Should().ThrowAsync<HttpRequestException>();
|
||||||
@@ -249,7 +249,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(addressJson);
|
handler.WithSuccessResponse(addressJson);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Addresses, ModelType.Address, null, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeOfType<Address>();
|
result.Should().BeOfType<Address>();
|
||||||
@@ -272,7 +272,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(addressArrayJson);
|
handler.WithSuccessResponse(addressArrayJson);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.subnets, types.Address, null, null, new[] { "10", "addresses" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Subnets, ModelType.Address, null, null, new[] { "10", "addresses" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeAssignableTo<IEnumerable<object>>();
|
result.Should().BeAssignableTo<IEnumerable<object>>();
|
||||||
@@ -300,7 +300,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(vlanJson);
|
handler.WithSuccessResponse(vlanJson);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.vlan, types.Vlan, null, null, new[] { "100" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Vlan, ModelType.Vlan, null, null, new[] { "100" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeOfType<Vlan>();
|
result.Should().BeOfType<Vlan>();
|
||||||
@@ -351,14 +351,14 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(subnetJson);
|
handler.WithSuccessResponse(subnetJson);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "1" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Subnets, ModelType.Subnetwork, null, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeOfType<Subnetwork>();
|
result.Should().BeOfType<Subnetwork>();
|
||||||
var subnet = (Subnetwork)result!;
|
var subnet = (Subnetwork)result!;
|
||||||
subnet.Subnet.Should().Be("192.168.1.0");
|
subnet.Subnet.Should().Be("192.168.1.0");
|
||||||
subnet.Mask.Should().Be(24);
|
subnet.Mask.Should().Be(24);
|
||||||
subnet.GetCIDR().Should().Be("192.168.1.0/24");
|
subnet.CIDR.Should().Be("192.168.1.0/24");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -386,7 +386,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(sectionJson);
|
handler.WithSuccessResponse(sectionJson);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { "1" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Sections, ModelType.Section, null, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeOfType<Section>();
|
result.Should().BeOfType<Section>();
|
||||||
@@ -411,12 +411,12 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(addressJson);
|
handler.WithSuccessResponse(addressJson);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "1" });
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Addresses, ModelType.Address, null, null, new[] { "1" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var address = (Address)result!;
|
var address = (Address)result!;
|
||||||
address.ExtendedData.Should().NotBeNull();
|
address.ExtendedData.Should().NotBeNull();
|
||||||
var extendedData = (Dictionary<string, object>)address.ExtendedData!;
|
var extendedData = address.ExtendedData!;
|
||||||
extendedData.Should().ContainKey("custom_environment");
|
extendedData.Should().ContainKey("custom_environment");
|
||||||
extendedData.Should().ContainKey("custom_owner");
|
extendedData.Should().ContainKey("custom_owner");
|
||||||
}
|
}
|
||||||
@@ -430,7 +430,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse(@"{""some"": ""data""}");
|
handler.WithSuccessResponse(@"{""some"": ""data""}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.tools);
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Tools);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().NotBeNull();
|
result.Should().NotBeNull();
|
||||||
@@ -447,7 +447,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
var parameters = new { ip = "10.0.0.1", subnetId = 5, description = "New address" };
|
var parameters = new { ip = "10.0.0.1", subnetId = 5, description = "New address" };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("POST", controllers.addresses, null, null, parameters);
|
await RequestHelper.InvokeRequest("POST", ApiController.Addresses, null, null, parameters);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.Content.Should().NotBeNull();
|
handler.LastRequest!.Content.Should().NotBeNull();
|
||||||
@@ -465,7 +465,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithSuccessResponse("{}");
|
handler.WithSuccessResponse("{}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
handler.LastRequest!.Headers.Accept.Should().Contain(h => h.MediaType == "application/json");
|
handler.LastRequest!.Headers.Accept.Should().Contain(h => h.MediaType == "application/json");
|
||||||
@@ -480,7 +480,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithResponse(HttpStatusCode.OK, "", "application/json");
|
handler.WithResponse(HttpStatusCode.OK, "", "application/json");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses);
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Addresses);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeNull();
|
result.Should().BeNull();
|
||||||
@@ -495,7 +495,7 @@ public class RequestHelperTests : IDisposable
|
|||||||
handler.WithJsonResponse(@"{""code"": 200, ""success"": true, ""data"": null}");
|
handler.WithJsonResponse(@"{""code"": 200, ""success"": true, ""data"": null}");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address);
|
var result = await RequestHelper.InvokeRequest("GET", ApiController.Addresses, ModelType.Address);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().BeNull();
|
result.Should().BeNull();
|
||||||
|
|||||||
@@ -21,60 +21,60 @@ public class SessionManagerTests : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TestSession_WhenNoSession_ReturnsNoToken()
|
public void GetSessionStatus_WhenNoSession_ReturnsNoSession()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
SessionManager.CurrentSession = null;
|
SessionManager.CurrentSession = null;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = SessionManager.TestSession();
|
var result = SessionManager.GetSessionStatus();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().Be("NoToken");
|
result.Should().Be(SessionStatus.NoSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TestSession_WhenSessionWithNullExpires_ReturnsValid()
|
public void GetSessionStatus_WhenSessionWithNullExpires_ReturnsValid()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var session = new Session(AuthType.token, "test-token", "app", "https://test.com", null, null);
|
var session = new Session(AuthType.Token, "test-token", "app", "https://test.com", null, null);
|
||||||
SessionManager.CurrentSession = session;
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = SessionManager.TestSession();
|
var result = SessionManager.GetSessionStatus();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().Be("Valid");
|
result.Should().Be(SessionStatus.Valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TestSession_WhenSessionNotExpired_ReturnsValid()
|
public void GetSessionStatus_WhenSessionNotExpired_ReturnsValid()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var futureExpiry = DateTime.Now.AddHours(1);
|
var futureExpiry = DateTime.Now.AddHours(1);
|
||||||
var session = new Session(AuthType.credentials, "test-token", "app", "https://test.com", futureExpiry, null);
|
var session = new Session(AuthType.Credentials, "test-token", "app", "https://test.com", futureExpiry, null);
|
||||||
SessionManager.CurrentSession = session;
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = SessionManager.TestSession();
|
var result = SessionManager.GetSessionStatus();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().Be("Valid");
|
result.Should().Be(SessionStatus.Valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TestSession_WhenSessionExpired_ReturnsExpired()
|
public void GetSessionStatus_WhenSessionExpired_ReturnsExpired()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var pastExpiry = DateTime.Now.AddHours(-1);
|
var pastExpiry = DateTime.Now.AddHours(-1);
|
||||||
var session = new Session(AuthType.credentials, "test-token", "app", "https://test.com", pastExpiry, null);
|
var session = new Session(AuthType.Credentials, "test-token", "app", "https://test.com", pastExpiry, null);
|
||||||
SessionManager.CurrentSession = session;
|
SessionManager.CurrentSession = session;
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = SessionManager.TestSession();
|
var result = SessionManager.GetSessionStatus();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().Be("Expired");
|
result.Should().Be(SessionStatus.Expired);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -93,7 +93,7 @@ public class SessionManagerTests : IDisposable
|
|||||||
session.URL.Should().Be(url);
|
session.URL.Should().Be(url);
|
||||||
session.AppID.Should().Be(appId);
|
session.AppID.Should().Be(appId);
|
||||||
session.Token.Should().Be(token);
|
session.Token.Should().Be(token);
|
||||||
session.AuthType.Should().Be(AuthType.token);
|
session.AuthType.Should().Be(AuthType.Token);
|
||||||
session.Expires.Should().BeNull();
|
session.Expires.Should().BeNull();
|
||||||
session.Credentials.Should().BeNull();
|
session.Credentials.Should().BeNull();
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ public class SessionManagerTests : IDisposable
|
|||||||
public void CurrentSession_CanBeSetDirectly()
|
public void CurrentSession_CanBeSetDirectly()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var session = new Session(AuthType.token, "token", "app", "https://test.com", null, null);
|
var session = new Session(AuthType.Token, "token", "app", "https://test.com", null, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
SessionManager.CurrentSession = session;
|
SessionManager.CurrentSession = session;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class AddressTests
|
|||||||
address.Note.Should().Be(note);
|
address.Note.Should().Be(note);
|
||||||
address.LastSeen.Should().Be(lastSeen);
|
address.LastSeen.Should().Be(lastSeen);
|
||||||
address.ExcludePing.Should().Be(excludePing);
|
address.ExcludePing.Should().Be(excludePing);
|
||||||
address.PTRignore.Should().Be(ptrIgnore);
|
address.PTRIgnore.Should().Be(ptrIgnore);
|
||||||
address.PTR.Should().Be(ptr);
|
address.PTR.Should().Be(ptr);
|
||||||
address.FirewallAddressObject.Should().Be(firewallObject);
|
address.FirewallAddressObject.Should().Be(firewallObject);
|
||||||
address.EditDate.Should().Be(editDate);
|
address.EditDate.Should().Be(editDate);
|
||||||
@@ -113,4 +113,24 @@ public class AddressTests
|
|||||||
// Act & Assert
|
// Act & Assert
|
||||||
address.ToString().Should().Be(expectedIp);
|
address.ToString().Should().Be(expectedIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Record_Equality_WorksCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var address1 = new Address(
|
||||||
|
1, 10, "192.168.1.1", false, "Test", "host", "", "",
|
||||||
|
0, 0, "", "", "", null, false,
|
||||||
|
false, 0, "", null, 0, null
|
||||||
|
);
|
||||||
|
|
||||||
|
var address2 = new Address(
|
||||||
|
1, 10, "192.168.1.1", false, "Test", "host", "", "",
|
||||||
|
0, 0, "", "", "", null, false,
|
||||||
|
false, 0, "", null, 0, null
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
address1.Should().Be(address2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class NameserverTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Constructor_WithEmptyNameservers_ReturnsArrayWithEmptyString()
|
public void Constructor_WithEmptyNameservers_ReturnsEmptyArray()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var nameServersString = "";
|
var nameServersString = "";
|
||||||
@@ -65,9 +65,8 @@ public class NameserverTests
|
|||||||
// Act
|
// Act
|
||||||
var nameserver = new Nameserver(1, "Test", nameServersString, "", "", null);
|
var nameserver = new Nameserver(1, "Test", nameServersString, "", "", null);
|
||||||
|
|
||||||
// Assert
|
// Assert - Empty entries are excluded
|
||||||
nameserver.NameServers.Should().HaveCount(1);
|
nameserver.NameServers.Should().BeEmpty();
|
||||||
nameserver.NameServers[0].Should().BeEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -79,4 +78,27 @@ public class NameserverTests
|
|||||||
// Assert
|
// Assert
|
||||||
nameserver.EditDate.Should().BeNull();
|
nameserver.EditDate.Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Constructor_WithSemicolonOnlyString_ReturnsEmptyArray()
|
||||||
|
{
|
||||||
|
// Arrange - edge case with just semicolons
|
||||||
|
var nameServersString = ";;;";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var nameserver = new Nameserver(1, "Test", nameServersString, "", "", null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
nameserver.NameServers.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToString_ReturnsName()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var nameserver = new Nameserver(1, "Google DNS", "8.8.8.8", "", "", null);
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
nameserver.ToString().Should().Be("Google DNS");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class SessionTests
|
|||||||
public void Constructor_WithCredentialsAuth_SetsAllProperties()
|
public void Constructor_WithCredentialsAuth_SetsAllProperties()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authType = AuthType.credentials;
|
var authType = AuthType.Credentials;
|
||||||
var token = "test-token-123";
|
var token = "test-token-123";
|
||||||
var appId = "myApp";
|
var appId = "myApp";
|
||||||
var url = "https://ipam.example.com";
|
var url = "https://ipam.example.com";
|
||||||
@@ -21,7 +21,7 @@ public class SessionTests
|
|||||||
var session = new Session(authType, token, appId, url, expires, credentials);
|
var session = new Session(authType, token, appId, url, expires, credentials);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
session.AuthType.Should().Be(AuthType.credentials);
|
session.AuthType.Should().Be(AuthType.Credentials);
|
||||||
session.Token.Should().Be(token);
|
session.Token.Should().Be(token);
|
||||||
session.AppID.Should().Be(appId);
|
session.AppID.Should().Be(appId);
|
||||||
session.URL.Should().Be(url);
|
session.URL.Should().Be(url);
|
||||||
@@ -33,7 +33,7 @@ public class SessionTests
|
|||||||
public void Constructor_WithTokenAuth_SetsAllProperties()
|
public void Constructor_WithTokenAuth_SetsAllProperties()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var authType = AuthType.token;
|
var authType = AuthType.Token;
|
||||||
var token = "static-api-token";
|
var token = "static-api-token";
|
||||||
var appId = "apiApp";
|
var appId = "apiApp";
|
||||||
var url = "https://ipam.test.com";
|
var url = "https://ipam.test.com";
|
||||||
@@ -42,7 +42,7 @@ public class SessionTests
|
|||||||
var session = new Session(authType, token, appId, url, null, null);
|
var session = new Session(authType, token, appId, url, null, null);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
session.AuthType.Should().Be(AuthType.token);
|
session.AuthType.Should().Be(AuthType.Token);
|
||||||
session.Token.Should().Be(token);
|
session.Token.Should().Be(token);
|
||||||
session.AppID.Should().Be(appId);
|
session.AppID.Should().Be(appId);
|
||||||
session.URL.Should().Be(url);
|
session.URL.Should().Be(url);
|
||||||
@@ -54,7 +54,7 @@ public class SessionTests
|
|||||||
public void Token_CanBeModified()
|
public void Token_CanBeModified()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var session = new Session(AuthType.credentials, "old-token", "app", "https://test.com", null, null);
|
var session = new Session(AuthType.Credentials, "old-token", "app", "https://test.com", null, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
session.Token = "new-token";
|
session.Token = "new-token";
|
||||||
@@ -67,7 +67,7 @@ public class SessionTests
|
|||||||
public void Expires_CanBeModified()
|
public void Expires_CanBeModified()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var session = new Session(AuthType.credentials, "token", "app", "https://test.com", null, null);
|
var session = new Session(AuthType.Credentials, "token", "app", "https://test.com", null, null);
|
||||||
var newExpiry = new DateTime(2027, 1, 1);
|
var newExpiry = new DateTime(2027, 1, 1);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -78,15 +78,13 @@ public class SessionTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ToString_ReturnsDefaultObjectString()
|
public void Record_Equality_WorksForSameValues()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var session = new Session(AuthType.token, "token", "app", "https://test.com", null, null);
|
var session1 = new Session(AuthType.Token, "token", "app", "https://test.com", null, null);
|
||||||
|
var session2 = new Session(AuthType.Token, "token", "app", "https://test.com", null, null);
|
||||||
|
|
||||||
// Act
|
// Assert - Records use value equality
|
||||||
var result = session.ToString();
|
session1.Should().Be(session2);
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().Contain("PS.IPAM.Session");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,13 +93,13 @@ public class SubnetworkTests
|
|||||||
[InlineData("10.0.0.0", 8, "10.0.0.0/8")]
|
[InlineData("10.0.0.0", 8, "10.0.0.0/8")]
|
||||||
[InlineData("172.16.0.0", 16, "172.16.0.0/16")]
|
[InlineData("172.16.0.0", 16, "172.16.0.0/16")]
|
||||||
[InlineData("192.168.100.0", 30, "192.168.100.0/30")]
|
[InlineData("192.168.100.0", 30, "192.168.100.0/30")]
|
||||||
public void GetCIDR_ReturnsCidrNotation(string subnet, int mask, string expectedCidr)
|
public void CIDR_ReturnsCidrNotation(string subnet, int mask, string expectedCidr)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var subnetwork = CreateSubnetwork(subnet, mask);
|
var subnetwork = CreateSubnetwork(subnet, mask);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = subnetwork.GetCIDR();
|
var result = subnetwork.CIDR;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().Be(expectedCidr);
|
result.Should().Be(expectedCidr);
|
||||||
@@ -119,16 +119,31 @@ public class SubnetworkTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ToString_EqualsGetCIDR()
|
public void ToString_EqualsCIDRProperty()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var subnetwork = CreateSubnetwork("172.20.0.0", 12);
|
var subnetwork = CreateSubnetwork("172.20.0.0", 12);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
subnetwork.ToString().Should().Be(subnetwork.GetCIDR());
|
subnetwork.ToString().Should().Be(subnetwork.CIDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Subnetwork CreateSubnetwork(string subnet, int mask)
|
[Fact]
|
||||||
|
public void Record_Equality_WorksCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange - use same calculation object for equality comparison
|
||||||
|
var calculation = new { maxhosts = 254 };
|
||||||
|
var subnet1 = CreateSubnetwork("192.168.1.0", 24, calculation);
|
||||||
|
var subnet2 = CreateSubnetwork("192.168.1.0", 24, calculation);
|
||||||
|
|
||||||
|
// Assert - records use value equality (except for the Calculation object reference)
|
||||||
|
subnet1.Id.Should().Be(subnet2.Id);
|
||||||
|
subnet1.Subnet.Should().Be(subnet2.Subnet);
|
||||||
|
subnet1.Mask.Should().Be(subnet2.Mask);
|
||||||
|
subnet1.CIDR.Should().Be(subnet2.CIDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Subnetwork CreateSubnetwork(string subnet, int mask, object? calculation = null)
|
||||||
{
|
{
|
||||||
return new Subnetwork(
|
return new Subnetwork(
|
||||||
1, subnet, mask, 1, "", "", "",
|
1, subnet, mask, 1, "", "", "",
|
||||||
@@ -136,7 +151,7 @@ public class SubnetworkTests
|
|||||||
"", false, false, false, false,
|
"", false, false, false, false,
|
||||||
false, 0, false, false, false, false,
|
false, 0, false, false, false, false,
|
||||||
0, 0, 0, null, null, null,
|
0, 0, 0, null, null, null,
|
||||||
new object(), null
|
calculation ?? new object(), null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,28 +26,13 @@ public class TagTests
|
|||||||
tag.Id.Should().Be(id);
|
tag.Id.Should().Be(id);
|
||||||
tag.Type.Should().Be(type);
|
tag.Type.Should().Be(type);
|
||||||
tag.ShowTag.Should().Be(showTag);
|
tag.ShowTag.Should().Be(showTag);
|
||||||
tag.BGColor.Should().Be(bgColor);
|
tag.BackgroundColor.Should().Be(bgColor);
|
||||||
tag.FGColor.Should().Be(fgColor);
|
tag.ForegroundColor.Should().Be(fgColor);
|
||||||
tag.Compress.Should().BeTrue();
|
tag.Compress.Should().Be(compress);
|
||||||
tag.Locked.Should().BeFalse();
|
tag.Locked.Should().Be(locked);
|
||||||
tag.UpdateTag.Should().Be(updateTag);
|
tag.UpdateTag.Should().Be(updateTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("Yes", true)]
|
|
||||||
[InlineData("No", false)]
|
|
||||||
[InlineData("", false)]
|
|
||||||
[InlineData("yes", false)] // Case sensitive
|
|
||||||
[InlineData("true", false)] // Only "Yes" is true
|
|
||||||
public void StringToBool_ConvertsCorrectly(string input, bool expected)
|
|
||||||
{
|
|
||||||
// The StringToBool is private, so we test through the constructor
|
|
||||||
// Using Compress field which uses StringToBool
|
|
||||||
var tag = new Tag(1, "Test", false, "", "", input, "No", false);
|
|
||||||
|
|
||||||
tag.Compress.Should().Be(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("Used")]
|
[InlineData("Used")]
|
||||||
[InlineData("Available")]
|
[InlineData("Available")]
|
||||||
@@ -66,12 +51,13 @@ public class TagTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Locked_WithYes_IsTrue()
|
public void Record_Equality_WorksCorrectly()
|
||||||
{
|
{
|
||||||
// Arrange & Act
|
// Arrange
|
||||||
var tag = new Tag(1, "Test", false, "", "", "No", "Yes", false);
|
var tag1 = new Tag(1, "Used", true, "#fff", "#000", "Yes", "No", false);
|
||||||
|
var tag2 = new Tag(1, "Used", true, "#fff", "#000", "Yes", "No", false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
tag.Locked.Should().BeTrue();
|
tag1.Should().Be(tag2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,30 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
[Cmdlet("Assign", "Tag")]
|
/// <summary>
|
||||||
public class AssignTagCmdlet : PSCmdlet
|
/// Assigns a tag to an address in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
|
[Cmdlet("Assign", "Tag", SupportsShouldProcess = true)]
|
||||||
|
[OutputType(typeof(Address))]
|
||||||
|
public class AssignTagCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0)]
|
Position = 0,
|
||||||
|
HelpMessage = "The address to assign the tag to.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Address? AddressObject { get; set; }
|
public Address? AddressObject { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
Position = 1)]
|
Position = 1,
|
||||||
|
HelpMessage = "The tag to assign.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Tag? Tag { get; set; }
|
public Tag? Tag { get; set; }
|
||||||
|
|
||||||
@@ -26,14 +32,25 @@ public class AssignTagCmdlet : PSCmdlet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string> { AddressObject!.Id.ToString() };
|
var identifiers = new[] { AddressObject!.Id.ToString() };
|
||||||
var body = new Dictionary<string, object>
|
var body = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "tag", Tag!.Id }
|
["tag"] = Tag!.Id
|
||||||
};
|
};
|
||||||
|
|
||||||
RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, body, identifiers.ToArray())
|
if (ShouldProcess($"Address {AddressObject.Ip}", $"Assign tag '{Tag.Type}'"))
|
||||||
.GetAwaiter().GetResult();
|
{
|
||||||
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the current phpIPAM API session.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Close, "Session")]
|
[Cmdlet(VerbsCommon.Close, "Session")]
|
||||||
public class CloseSessionCmdlet : PSCmdlet
|
public class CloseSessionCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
RequestHelper.InvokeRequest("DELETE", controllers.user, null, null, null, null)
|
|
||||||
.GetAwaiter().GetResult();
|
|
||||||
SessionManager.CloseSession();
|
SessionManager.CloseSession();
|
||||||
}
|
WriteVerbose("Session closed successfully.");
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
WriteError(new ErrorRecord(ex, "CloseSessionError", ErrorCategory.InvalidOperation, null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves IP address entries from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Address", DefaultParameterSetName = "ByID")]
|
[Cmdlet(VerbsCommon.Get, "Address", DefaultParameterSetName = "ByID")]
|
||||||
[OutputType(typeof(Address))]
|
[OutputType(typeof(Address))]
|
||||||
public class GetAddressCmdlet : PSCmdlet
|
public class GetAddressCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The address ID to retrieve.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
@@ -24,7 +28,8 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByIP")]
|
ParameterSetName = "ByIP",
|
||||||
|
HelpMessage = "The IP address to search for.")]
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
@@ -39,7 +44,8 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByHostName")]
|
ParameterSetName = "ByHostName",
|
||||||
|
HelpMessage = "The hostname to search for.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? HostName { get; set; }
|
public string? HostName { get; set; }
|
||||||
|
|
||||||
@@ -48,7 +54,8 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByHostBase")]
|
ParameterSetName = "ByHostBase",
|
||||||
|
HelpMessage = "The hostname base pattern to search for.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? HostBase { get; set; }
|
public string? HostBase { get; set; }
|
||||||
|
|
||||||
@@ -57,7 +64,8 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByTag")]
|
ParameterSetName = "ByTag",
|
||||||
|
HelpMessage = "The tag ID to filter addresses by.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? TagId { get; set; }
|
public int? TagId { get; set; }
|
||||||
|
|
||||||
@@ -66,7 +74,8 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetId")]
|
ParameterSetName = "BySubnetId",
|
||||||
|
HelpMessage = "The subnet ID to get addresses from.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? SubnetId { get; set; }
|
public int? SubnetId { get; set; }
|
||||||
|
|
||||||
@@ -75,7 +84,8 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetCIDR")]
|
ParameterSetName = "BySubnetCIDR",
|
||||||
|
HelpMessage = "The subnet in CIDR notation to get addresses from.")]
|
||||||
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? SubnetCIDR { get; set; }
|
public string? SubnetCIDR { get; set; }
|
||||||
@@ -84,7 +94,7 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var controller = controllers.addresses;
|
var controller = ApiController.Addresses;
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
switch (ParameterSetName)
|
switch (ParameterSetName)
|
||||||
@@ -92,23 +102,28 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
case "ByID":
|
case "ByID":
|
||||||
identifiers.Add(Id.ToString());
|
identifiers.Add(Id.ToString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByIP":
|
case "ByIP":
|
||||||
identifiers.Add("search");
|
identifiers.Add("search");
|
||||||
identifiers.Add(IP!.ToString());
|
identifiers.Add(IP!.ToString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByHostName":
|
case "ByHostName":
|
||||||
identifiers.Add("search_hostname");
|
identifiers.Add("search_hostname");
|
||||||
identifiers.Add(HostName!);
|
identifiers.Add(HostName!);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByHostBase":
|
case "ByHostBase":
|
||||||
identifiers.Add("search_hostbase");
|
identifiers.Add("search_hostbase");
|
||||||
identifiers.Add(HostBase!);
|
identifiers.Add(HostBase!);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByTag":
|
case "ByTag":
|
||||||
identifiers.Add("tags");
|
identifiers.Add("tags");
|
||||||
identifiers.Add(TagId!.Value.ToString());
|
identifiers.Add(TagId!.Value.ToString());
|
||||||
identifiers.Add("addresses");
|
identifiers.Add("addresses");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySubnetId":
|
case "BySubnetId":
|
||||||
if (IP != null)
|
if (IP != null)
|
||||||
{
|
{
|
||||||
@@ -117,42 +132,34 @@ public class GetAddressCmdlet : PSCmdlet
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
controller = controllers.subnets;
|
controller = ApiController.Subnets;
|
||||||
identifiers.Add(SubnetId!.Value.ToString());
|
identifiers.Add(SubnetId!.Value.ToString());
|
||||||
identifiers.Add("addresses");
|
identifiers.Add("addresses");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySubnetCIDR":
|
case "BySubnetCIDR":
|
||||||
controller = controllers.subnets;
|
controller = ApiController.Subnets;
|
||||||
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", SubnetCIDR! })
|
var subnet = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
|
||||||
|
new[] { "cidr", SubnetCIDR! }
|
||||||
|
).GetAwaiter().GetResult() as Subnetwork;
|
||||||
|
|
||||||
if (subnet == null)
|
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");
|
identifiers.Add("addresses");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controller, types.Address, null, null, identifiers.ToArray())
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", controller, ModelType.Address, null, null, identifiers.ToArray()
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the first available IP address in a subnet.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "FirstFreeIP", DefaultParameterSetName = "ByID")]
|
[Cmdlet(VerbsCommon.Get, "FirstFreeIP", DefaultParameterSetName = "ByID")]
|
||||||
public class GetFirstFreeIPCmdlet : PSCmdlet
|
public class GetFirstFreeIPCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByCIDR")]
|
ParameterSetName = "ByCIDR",
|
||||||
|
HelpMessage = "The subnet in CIDR notation.")]
|
||||||
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? CIDR { get; set; }
|
public string? CIDR { get; set; }
|
||||||
@@ -24,7 +27,8 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The subnet ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -33,7 +37,8 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetObject")]
|
ParameterSetName = "BySubnetObject",
|
||||||
|
HelpMessage = "The subnet object.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Subnetwork? SubnetObject { get; set; }
|
public Subnetwork? SubnetObject { get; set; }
|
||||||
|
|
||||||
@@ -41,30 +46,12 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int subnetId;
|
var subnetId = GetSubnetId();
|
||||||
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 identifiers = new List<string> { subnetId.ToString(), "first_free" };
|
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)
|
if (result != null)
|
||||||
{
|
{
|
||||||
@@ -76,4 +63,28 @@ public class GetFirstFreeIPCmdlet : PSCmdlet
|
|||||||
WriteError(new ErrorRecord(ex, "GetFirstFreeIPError", ErrorCategory.InvalidOperation, null));
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves L2 domain information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "L2Domain", DefaultParameterSetName = "ByID")]
|
[Cmdlet(VerbsCommon.Get, "L2Domain", DefaultParameterSetName = "ByID")]
|
||||||
[OutputType(typeof(Domain))]
|
[OutputType(typeof(Domain))]
|
||||||
public class GetL2DomainCmdlet : PSCmdlet
|
public class GetL2DomainCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The L2 domain ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,28 +27,18 @@ public class GetL2DomainCmdlet : PSCmdlet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
if (Id.HasValue)
|
if (Id.HasValue)
|
||||||
{
|
{
|
||||||
identifiers.Add(Id.Value.ToString());
|
identifiers.Add(Id.Value.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controllers.l2domains, types.Domain, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.L2Domains, ModelType.Domain, null, null,
|
||||||
|
identifiers.Count > 0 ? identifiers.ToArray() : null
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves nameserver information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Nameserver", DefaultParameterSetName = "NoParams")]
|
[Cmdlet(VerbsCommon.Get, "Nameserver", DefaultParameterSetName = "NoParams")]
|
||||||
[OutputType(typeof(Nameserver))]
|
[OutputType(typeof(Nameserver))]
|
||||||
public class GetNameserverCmdlet : PSCmdlet
|
public class GetNameserverCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The nameserver ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,28 +27,18 @@ public class GetNameserverCmdlet : PSCmdlet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
if (Id.HasValue)
|
if (Id.HasValue)
|
||||||
{
|
{
|
||||||
identifiers.Add(Id.Value.ToString());
|
identifiers.Add(Id.Value.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controllers.tools, types.Nameserver, subcontrollers.nameservers, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Tools, ModelType.Nameserver, ApiSubController.Nameservers,
|
||||||
|
null, identifiers.Count > 0 ? identifiers.ToArray() : null
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves permission information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Permissions")]
|
[Cmdlet(VerbsCommon.Get, "Permissions")]
|
||||||
public class GetPermissionsCmdlet : PSCmdlet
|
public class GetPermissionsCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The address ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? Id { get; set; }
|
public string? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,7 +27,8 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByIP")]
|
ParameterSetName = "ByIP",
|
||||||
|
HelpMessage = "The IP address to search for.")]
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
@@ -38,7 +43,8 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByHostName")]
|
ParameterSetName = "ByHostName",
|
||||||
|
HelpMessage = "The hostname to search for.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? HostName { get; set; }
|
public string? HostName { get; set; }
|
||||||
|
|
||||||
@@ -47,7 +53,8 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByTag")]
|
ParameterSetName = "ByTag",
|
||||||
|
HelpMessage = "The tag ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? TagId { get; set; }
|
public string? TagId { get; set; }
|
||||||
|
|
||||||
@@ -56,7 +63,8 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetId")]
|
ParameterSetName = "BySubnetId",
|
||||||
|
HelpMessage = "The subnet ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? SubnetId { get; set; }
|
public string? SubnetId { get; set; }
|
||||||
|
|
||||||
@@ -65,7 +73,8 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetCIDR")]
|
ParameterSetName = "BySubnetCIDR",
|
||||||
|
HelpMessage = "The subnet in CIDR notation.")]
|
||||||
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? SubnetCIDR { get; set; }
|
public string? SubnetCIDR { get; set; }
|
||||||
@@ -74,7 +83,7 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var controller = controllers.addresses;
|
var controller = ApiController.Addresses;
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
switch (ParameterSetName)
|
switch (ParameterSetName)
|
||||||
@@ -82,19 +91,23 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
case "ByID":
|
case "ByID":
|
||||||
identifiers.Add(Id!);
|
identifiers.Add(Id!);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByIP":
|
case "ByIP":
|
||||||
identifiers.Add("search");
|
identifiers.Add("search");
|
||||||
identifiers.Add(IP!.ToString());
|
identifiers.Add(IP!.ToString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByHostName":
|
case "ByHostName":
|
||||||
identifiers.Add("search_hostname");
|
identifiers.Add("search_hostname");
|
||||||
identifiers.Add(HostName!);
|
identifiers.Add(HostName!);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByTag":
|
case "ByTag":
|
||||||
identifiers.Add("tags");
|
identifiers.Add("tags");
|
||||||
identifiers.Add(TagId!);
|
identifiers.Add(TagId!);
|
||||||
identifiers.Add("addresses");
|
identifiers.Add("addresses");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySubnetId":
|
case "BySubnetId":
|
||||||
if (IP != null)
|
if (IP != null)
|
||||||
{
|
{
|
||||||
@@ -103,42 +116,34 @@ public class GetPermissionsCmdlet : PSCmdlet
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
controller = controllers.subnets;
|
controller = ApiController.Subnets;
|
||||||
identifiers.Add(SubnetId!);
|
identifiers.Add(SubnetId!);
|
||||||
identifiers.Add("addresses");
|
identifiers.Add("addresses");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySubnetCIDR":
|
case "BySubnetCIDR":
|
||||||
controller = controllers.subnets;
|
controller = ApiController.Subnets;
|
||||||
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", SubnetCIDR! })
|
var subnet = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
|
||||||
|
new[] { "cidr", SubnetCIDR! }
|
||||||
|
).GetAwaiter().GetResult() as Subnetwork;
|
||||||
|
|
||||||
if (subnet == null)
|
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");
|
identifiers.Add("addresses");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controller, null, null, null, identifiers.ToArray())
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", controller, null, null, null, identifiers.ToArray()
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves section information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Section", DefaultParameterSetName = "NoParams")]
|
[Cmdlet(VerbsCommon.Get, "Section", DefaultParameterSetName = "NoParams")]
|
||||||
[OutputType(typeof(Section))]
|
[OutputType(typeof(Section))]
|
||||||
public class GetSectionCmdlet : PSCmdlet
|
public class GetSectionCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The section ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -21,7 +25,8 @@ public class GetSectionCmdlet : PSCmdlet
|
|||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByName")]
|
ParameterSetName = "ByName",
|
||||||
|
HelpMessage = "The section name.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
@@ -30,6 +35,7 @@ public class GetSectionCmdlet : PSCmdlet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
if (ParameterSetName == "ByID" && Id.HasValue)
|
if (ParameterSetName == "ByID" && Id.HasValue)
|
||||||
{
|
{
|
||||||
identifiers.Add(Id.Value.ToString());
|
identifiers.Add(Id.Value.ToString());
|
||||||
@@ -39,23 +45,12 @@ public class GetSectionCmdlet : PSCmdlet
|
|||||||
identifiers.Add(Name!);
|
identifiers.Add(Name!);
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Sections, ModelType.Section, null, null,
|
||||||
|
identifiers.Count > 0 ? identifiers.ToArray() : null
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves subnet information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Subnet", DefaultParameterSetName = "NoParams")]
|
[Cmdlet(VerbsCommon.Get, "Subnet", DefaultParameterSetName = "NoParams")]
|
||||||
[OutputType(typeof(Subnetwork))]
|
[OutputType(typeof(Subnetwork))]
|
||||||
public class GetSubnetCmdlet : PSCmdlet
|
public class GetSubnetCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
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}$")]
|
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? CIDR { get; set; }
|
public string? CIDR { get; set; }
|
||||||
@@ -26,7 +28,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The subnet ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -35,7 +38,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySectionId")]
|
ParameterSetName = "BySectionId",
|
||||||
|
HelpMessage = "The section ID to get subnets from.")]
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
@@ -56,7 +60,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySectionName")]
|
ParameterSetName = "BySectionName",
|
||||||
|
HelpMessage = "The section name to get subnets from.")]
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
@@ -77,7 +82,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByVrfId")]
|
ParameterSetName = "ByVrfId",
|
||||||
|
HelpMessage = "The VRF ID to get subnets from.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? VrfId { get; set; }
|
public int? VrfId { get; set; }
|
||||||
|
|
||||||
@@ -86,7 +92,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByVlanId")]
|
ParameterSetName = "ByVlanId",
|
||||||
|
HelpMessage = "The VLAN ID to get subnets from.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? VlanId { get; set; }
|
public int? VlanId { get; set; }
|
||||||
|
|
||||||
@@ -95,7 +102,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByVlanNumber")]
|
ParameterSetName = "ByVlanNumber",
|
||||||
|
HelpMessage = "The VLAN number to get subnets from.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? VlanNumber { get; set; }
|
public int? VlanNumber { get; set; }
|
||||||
|
|
||||||
@@ -104,7 +112,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 1,
|
Position = 1,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "Get child subnets (slaves).")]
|
||||||
public SwitchParameter Slaves { get; set; }
|
public SwitchParameter Slaves { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(
|
||||||
@@ -112,7 +121,8 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 2,
|
Position = 2,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "Get child subnets recursively.")]
|
||||||
public SwitchParameter Recurse { get; set; }
|
public SwitchParameter Recurse { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(
|
||||||
@@ -120,16 +130,16 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 1,
|
Position = 1,
|
||||||
ParameterSetName = "ByVlanNumber")]
|
ParameterSetName = "ByVlanNumber",
|
||||||
|
HelpMessage = "The L2 domain ID to narrow VLAN search.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? VlanDomainId { get; set; }
|
public int? VlanDomainId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var controller = controllers.subnets;
|
var controller = ApiController.Subnets;
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
switch (ParameterSetName)
|
switch (ParameterSetName)
|
||||||
@@ -138,6 +148,7 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
identifiers.Add("cidr");
|
identifiers.Add("cidr");
|
||||||
identifiers.Add(CIDR!);
|
identifiers.Add(CIDR!);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByID":
|
case "ByID":
|
||||||
identifiers.Add(Id!.Value.ToString());
|
identifiers.Add(Id!.Value.ToString());
|
||||||
if (Slaves.IsPresent)
|
if (Slaves.IsPresent)
|
||||||
@@ -145,117 +156,122 @@ public class GetSubnetCmdlet : PSCmdlet
|
|||||||
identifiers.Add(Recurse.IsPresent ? "slaves_recursive" : "slaves");
|
identifiers.Add(Recurse.IsPresent ? "slaves_recursive" : "slaves");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySectionId":
|
case "BySectionId":
|
||||||
controller = controllers.sections;
|
controller = ApiController.Sections;
|
||||||
identifiers.Add(SectionId!.Value.ToString());
|
identifiers.Add(SectionId!.Value.ToString());
|
||||||
identifiers.Add("subnets");
|
identifiers.Add("subnets");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySectionName":
|
case "BySectionName":
|
||||||
controller = controllers.sections;
|
controller = ApiController.Sections;
|
||||||
var section = RequestHelper.InvokeRequest("GET", controllers.sections, types.Section, null, null, new[] { SectionName! })
|
var section = GetSectionByName(SectionName!);
|
||||||
.GetAwaiter().GetResult();
|
identifiers.Add(section.Id.ToString());
|
||||||
if (section == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Cannot find section!");
|
|
||||||
}
|
|
||||||
var sectionObj = section as Section;
|
|
||||||
identifiers.Add(sectionObj!.Id.ToString());
|
|
||||||
identifiers.Add("subnets");
|
identifiers.Add("subnets");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByVrfId":
|
case "ByVrfId":
|
||||||
controller = controllers.vrf;
|
controller = ApiController.Vrf;
|
||||||
identifiers.Add(VrfId!.Value.ToString());
|
identifiers.Add(VrfId!.Value.ToString());
|
||||||
identifiers.Add("subnets");
|
identifiers.Add("subnets");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByVlanId":
|
case "ByVlanId":
|
||||||
controller = controllers.vlan;
|
controller = ApiController.Vlan;
|
||||||
identifiers.Add(VlanId!.Value.ToString());
|
identifiers.Add(VlanId!.Value.ToString());
|
||||||
identifiers.Add("subnets");
|
identifiers.Add("subnets");
|
||||||
if (SectionId.HasValue)
|
AddSectionIdentifier(identifiers);
|
||||||
{
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByVlanNumber":
|
case "ByVlanNumber":
|
||||||
controller = controllers.vlan;
|
controller = ApiController.Vlan;
|
||||||
var vlans = RequestHelper.InvokeRequest("GET", controllers.vlan, types.Vlan, null, null, new[] { "search", VlanNumber!.Value.ToString() })
|
var vlan = FindVlanByNumber(VlanNumber!.Value, VlanDomainId);
|
||||||
.GetAwaiter().GetResult();
|
identifiers.Add(vlan.Id.ToString());
|
||||||
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());
|
|
||||||
identifiers.Add("subnets");
|
identifiers.Add("subnets");
|
||||||
if (SectionId.HasValue)
|
AddSectionIdentifier(identifiers);
|
||||||
{
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controller, types.Subnetwork, null, null, identifiers.ToArray())
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", controller, ModelType.Subnetwork, null, null, identifiers.ToArray()
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteError(new ErrorRecord(ex, "GetSubnetError", ErrorCategory.InvalidOperation, null));
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves subnet usage statistics from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "SubnetUsage", DefaultParameterSetName = "ByID")]
|
[Cmdlet(VerbsCommon.Get, "SubnetUsage", DefaultParameterSetName = "ByID")]
|
||||||
public class GetSubnetUsageCmdlet : PSCmdlet
|
public class GetSubnetUsageCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByCIDR")]
|
ParameterSetName = "ByCIDR",
|
||||||
|
HelpMessage = "The subnet in CIDR notation.")]
|
||||||
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? CIDR { get; set; }
|
public string? CIDR { get; set; }
|
||||||
@@ -24,43 +27,60 @@ public class GetSubnetUsageCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The subnet ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
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()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int subnetId;
|
var subnetId = GetSubnetId();
|
||||||
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 identifiers = new List<string> { subnetId.ToString(), "usage" };
|
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)
|
var result = RequestHelper.InvokeRequest(
|
||||||
{
|
"GET", ApiController.Subnets, null, null, null, identifiers.ToArray()
|
||||||
WriteObject(result);
|
).GetAwaiter().GetResult();
|
||||||
}
|
|
||||||
|
WriteResult(result);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteError(new ErrorRecord(ex, "GetSubnetUsageError", ErrorCategory.InvalidOperation, null));
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves tag information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Tag", DefaultParameterSetName = "NoParams")]
|
[Cmdlet(VerbsCommon.Get, "Tag", DefaultParameterSetName = "NoParams")]
|
||||||
[OutputType(typeof(Tag))]
|
[OutputType(typeof(Tag))]
|
||||||
public class GetTagCmdlet : PSCmdlet
|
public class GetTagCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The tag ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,7 +27,8 @@ public class GetTagCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByAddressObject")]
|
ParameterSetName = "ByAddressObject",
|
||||||
|
HelpMessage = "Get the tag associated with this address.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Address? AddressObject { get; set; }
|
public Address? AddressObject { get; set; }
|
||||||
|
|
||||||
@@ -32,7 +37,8 @@ public class GetTagCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetObject")]
|
ParameterSetName = "BySubnetObject",
|
||||||
|
HelpMessage = "Get the tag associated with this subnet.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Subnetwork? SubnetObject { get; set; }
|
public Subnetwork? SubnetObject { get; set; }
|
||||||
|
|
||||||
@@ -50,6 +56,7 @@ public class GetTagCmdlet : PSCmdlet
|
|||||||
identifiers.Add(Id.Value.ToString());
|
identifiers.Add(Id.Value.ToString());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByAddressObject":
|
case "ByAddressObject":
|
||||||
if (AddressObject?.TagId > 0)
|
if (AddressObject?.TagId > 0)
|
||||||
{
|
{
|
||||||
@@ -60,6 +67,7 @@ public class GetTagCmdlet : PSCmdlet
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySubnetObject":
|
case "BySubnetObject":
|
||||||
if (SubnetObject?.TagId > 0)
|
if (SubnetObject?.TagId > 0)
|
||||||
{
|
{
|
||||||
@@ -72,23 +80,11 @@ public class GetTagCmdlet : PSCmdlet
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Tag, null, null, identifiers.ToArray())
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Addresses, ModelType.Tag, null, null, identifiers.ToArray()
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves VLAN information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Vlan", DefaultParameterSetName = "NoParams")]
|
[Cmdlet(VerbsCommon.Get, "Vlan", DefaultParameterSetName = "NoParams")]
|
||||||
[OutputType(typeof(Vlan))]
|
[OutputType(typeof(Vlan))]
|
||||||
public class GetVlanCmdlet : PSCmdlet
|
public class GetVlanCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The VLAN ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,7 +27,8 @@ public class GetVlanCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByNumber")]
|
ParameterSetName = "ByNumber",
|
||||||
|
HelpMessage = "The VLAN number.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Number { get; set; }
|
public int? Number { get; set; }
|
||||||
|
|
||||||
@@ -32,7 +37,8 @@ public class GetVlanCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByL2Domain")]
|
ParameterSetName = "ByL2Domain",
|
||||||
|
HelpMessage = "The L2 domain ID to get VLANs from.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? L2DomainId { get; set; }
|
public int? L2DomainId { get; set; }
|
||||||
|
|
||||||
@@ -41,7 +47,8 @@ public class GetVlanCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetObject")]
|
ParameterSetName = "BySubnetObject",
|
||||||
|
HelpMessage = "Get the VLAN associated with this subnet.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Subnetwork? SubnetObject { get; set; }
|
public Subnetwork? SubnetObject { get; set; }
|
||||||
|
|
||||||
@@ -50,7 +57,8 @@ public class GetVlanCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByDomainObject")]
|
ParameterSetName = "ByDomainObject",
|
||||||
|
HelpMessage = "Get VLANs in this L2 domain.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Domain? DomainObject { get; set; }
|
public Domain? DomainObject { get; set; }
|
||||||
|
|
||||||
@@ -58,7 +66,7 @@ public class GetVlanCmdlet : PSCmdlet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var controller = controllers.vlan;
|
var controller = ApiController.Vlan;
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
switch (ParameterSetName)
|
switch (ParameterSetName)
|
||||||
@@ -66,65 +74,44 @@ public class GetVlanCmdlet : PSCmdlet
|
|||||||
case "ByID":
|
case "ByID":
|
||||||
identifiers.Add(Id!.Value.ToString());
|
identifiers.Add(Id!.Value.ToString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByNumber":
|
case "ByNumber":
|
||||||
identifiers.Add("search");
|
identifiers.Add("search");
|
||||||
identifiers.Add(Number!.Value.ToString());
|
identifiers.Add(Number!.Value.ToString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByL2Domain":
|
case "ByL2Domain":
|
||||||
controller = controllers.l2domains;
|
controller = ApiController.L2Domains;
|
||||||
identifiers.Add(L2DomainId!.Value.ToString());
|
identifiers.Add(L2DomainId!.Value.ToString());
|
||||||
identifiers.Add(subcontrollers.vlans.ToString());
|
identifiers.Add(ApiSubController.Vlans.ToString().ToLowerInvariant());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "BySubnetObject":
|
case "BySubnetObject":
|
||||||
if (SubnetObject != null && SubnetObject.VlanId > 0)
|
if (SubnetObject == null || SubnetObject.VlanId <= 0)
|
||||||
{
|
|
||||||
identifiers.Add(SubnetObject.VlanId.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
identifiers.Add(SubnetObject.VlanId.ToString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ByDomainObject":
|
case "ByDomainObject":
|
||||||
if (DomainObject != null)
|
if (DomainObject != null)
|
||||||
{
|
{
|
||||||
var result = RequestHelper.InvokeRequest("GET", controllers.l2domains, types.Vlan, subcontrollers.vlans, null, new[] { DomainObject.Id.ToString() })
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.L2Domains, ModelType.Vlan, ApiSubController.Vlans,
|
||||||
if (result != null)
|
null, new[] { DomainObject.Id.ToString() }
|
||||||
{
|
).GetAwaiter().GetResult();
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
WriteResult(result);
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var vlanResult = RequestHelper.InvokeRequest("GET", controller, types.Vlan, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
|
var vlanResult = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", controller, ModelType.Vlan, null, null,
|
||||||
|
identifiers.Count > 0 ? identifiers.ToArray() : null
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (vlanResult != null)
|
WriteResult(vlanResult);
|
||||||
{
|
|
||||||
if (vlanResult is System.Collections.IEnumerable enumerable && !(vlanResult is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(vlanResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves VRF information from phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Get, "Vrf", DefaultParameterSetName = "NoParams")]
|
[Cmdlet(VerbsCommon.Get, "Vrf", DefaultParameterSetName = "NoParams")]
|
||||||
[OutputType(typeof(Vrf))]
|
[OutputType(typeof(Vrf))]
|
||||||
public class GetVrfCmdlet : PSCmdlet
|
public class GetVrfCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByID")]
|
ParameterSetName = "ByID",
|
||||||
|
HelpMessage = "The VRF ID.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,28 +27,18 @@ public class GetVrfCmdlet : PSCmdlet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string>();
|
var identifiers = new List<string>();
|
||||||
|
|
||||||
if (Id.HasValue)
|
if (Id.HasValue)
|
||||||
{
|
{
|
||||||
identifiers.Add(Id.Value.ToString());
|
identifiers.Add(Id.Value.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = RequestHelper.InvokeRequest("GET", controllers.vrf, types.Vrf, null, null, identifiers.Count > 0 ? identifiers.ToArray() : null)
|
var result = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Vrf, ModelType.Vrf, null, null,
|
||||||
|
identifiers.Count > 0 ? identifiers.ToArray() : null
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (result != null)
|
WriteResult(result);
|
||||||
{
|
|
||||||
if (result is System.Collections.IEnumerable enumerable && !(result is string))
|
|
||||||
{
|
|
||||||
foreach (var item in enumerable)
|
|
||||||
{
|
|
||||||
WriteObject(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new IP address entry in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.New, "Address", DefaultParameterSetName = "BySubnetId")]
|
[Cmdlet(VerbsCommon.New, "Address", DefaultParameterSetName = "BySubnetId")]
|
||||||
[OutputType(typeof(Address))]
|
[OutputType(typeof(Address))]
|
||||||
public class NewAddressCmdlet : PSCmdlet
|
public class NewAddressCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetId")]
|
ParameterSetName = "BySubnetId",
|
||||||
|
HelpMessage = "The subnet ID to create the address in.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? SubnetId { get; set; }
|
public int? SubnetId { get; set; }
|
||||||
|
|
||||||
@@ -24,7 +27,8 @@ public class NewAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "BySubnetObject")]
|
ParameterSetName = "BySubnetObject",
|
||||||
|
HelpMessage = "The subnet object to create the address in.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Subnetwork? SubnetObject { get; set; }
|
public Subnetwork? SubnetObject { get; set; }
|
||||||
|
|
||||||
@@ -32,166 +36,73 @@ public class NewAddressCmdlet : PSCmdlet
|
|||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 1)]
|
Position = 1,
|
||||||
|
HelpMessage = "The IP address to create.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string IP { get; set; } = string.Empty;
|
public string IP { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Mark this address as a gateway.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 2)]
|
|
||||||
public SwitchParameter Gateway { get; set; }
|
public SwitchParameter Gateway { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 3, HelpMessage = "Description for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 3)]
|
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 4, HelpMessage = "Hostname for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 4)]
|
|
||||||
public string? Hostname { get; set; }
|
public string? Hostname { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 5, HelpMessage = "MAC address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 5)]
|
|
||||||
public string? MAC { get; set; }
|
public string? MAC { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 6, HelpMessage = "Owner of the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 6)]
|
|
||||||
public string? Owner { get; set; }
|
public string? Owner { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 7, HelpMessage = "Tag ID for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 7)]
|
|
||||||
public int? TagId { get; set; }
|
public int? TagId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 8, HelpMessage = "Ignore PTR record generation.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 8)]
|
|
||||||
public SwitchParameter PTRIgnore { get; set; }
|
public SwitchParameter PTRIgnore { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 9, HelpMessage = "PTR record ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 7)]
|
|
||||||
public int? PTRId { get; set; }
|
public int? PTRId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 10, HelpMessage = "Note for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 10)]
|
|
||||||
public string? Note { get; set; }
|
public string? Note { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 11, HelpMessage = "Exclude from ping scanning.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 11)]
|
|
||||||
public SwitchParameter ExcludePing { get; set; }
|
public SwitchParameter ExcludePing { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 12, HelpMessage = "Associated device ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 12)]
|
|
||||||
public int? DeviceId { get; set; }
|
public int? DeviceId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 13, HelpMessage = "Port information.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 13)]
|
|
||||||
public string? Port { get; set; }
|
public string? Port { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 14, HelpMessage = "Custom fields as a hashtable or PSObject.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 14)]
|
|
||||||
public object? CustomFields { get; set; }
|
public object? CustomFields { get; set; }
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int actualSubnetId;
|
var actualSubnetId = ParameterSetName == "BySubnetObject"
|
||||||
if (ParameterSetName == "BySubnetObject")
|
? SubnetObject!.Id
|
||||||
{
|
: SubnetId!.Value;
|
||||||
actualSubnetId = SubnetObject!.Id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
actualSubnetId = SubnetId!.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var body = new Dictionary<string, object>
|
var body = BuildRequestBody(actualSubnetId);
|
||||||
{
|
|
||||||
{ "subnetId", actualSubnetId },
|
|
||||||
{ "ip", IP }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Gateway.IsPresent)
|
var result = RequestHelper.InvokeRequest(
|
||||||
body["is_gateway"] = "1";
|
"POST", ApiController.Addresses, null, null, body
|
||||||
if (!string.IsNullOrEmpty(Description))
|
).GetAwaiter().GetResult();
|
||||||
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();
|
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "search", IP })
|
// Fetch the created address to return it
|
||||||
.GetAwaiter().GetResult();
|
var address = RequestHelper.InvokeRequest(
|
||||||
if (address != null)
|
"GET", ApiController.Addresses, ModelType.Address, null, null,
|
||||||
{
|
new[] { "search", IP }
|
||||||
WriteObject(address);
|
).GetAwaiter().GetResult();
|
||||||
}
|
|
||||||
|
WriteResult(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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>();
|
var body = new Dictionary<string, object>
|
||||||
if (customFields is PSObject psobj)
|
|
||||||
{
|
{
|
||||||
foreach (var prop in psobj.Properties)
|
["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))
|
||||||
{
|
{
|
||||||
dict[prop.Name] = prop.Value ?? new object();
|
body[kvp.Key] = kvp.Value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (customFields is Dictionary<string, object> dictObj)
|
return body;
|
||||||
{
|
|
||||||
return dictObj;
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,168 +1,85 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new address using the first available IP in a subnet.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.New, "FirstFreeIP")]
|
[Cmdlet(VerbsCommon.New, "FirstFreeIP")]
|
||||||
[OutputType(typeof(Address))]
|
[OutputType(typeof(Address))]
|
||||||
public class NewFirstFreeIPCmdlet : PSCmdlet
|
public class NewFirstFreeIPCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0)]
|
Position = 0,
|
||||||
|
HelpMessage = "The subnet ID to create the address in.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string SubnetId { get; set; } = string.Empty;
|
public string SubnetId { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 1, HelpMessage = "Mark this address as a gateway.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 2)]
|
|
||||||
public SwitchParameter Gateway { get; set; }
|
public SwitchParameter Gateway { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Description for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 3)]
|
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 3, HelpMessage = "Hostname for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 4)]
|
|
||||||
public string? Hostname { get; set; }
|
public string? Hostname { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 4, HelpMessage = "MAC address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 5)]
|
|
||||||
public string? MAC { get; set; }
|
public string? MAC { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 5, HelpMessage = "Owner of the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 6)]
|
|
||||||
public string? Owner { get; set; }
|
public string? Owner { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 6, HelpMessage = "Tag ID for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 7)]
|
|
||||||
public string? TagId { get; set; }
|
public string? TagId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 7, HelpMessage = "Ignore PTR record generation.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 8)]
|
|
||||||
public SwitchParameter PTRIgnore { get; set; }
|
public SwitchParameter PTRIgnore { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 8, HelpMessage = "PTR record ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 9)]
|
|
||||||
public string? PTRId { get; set; }
|
public string? PTRId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 9, HelpMessage = "Note for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 10)]
|
|
||||||
public string? Note { get; set; }
|
public string? Note { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 10, HelpMessage = "Exclude from ping scanning.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 11)]
|
|
||||||
public SwitchParameter ExcludePing { get; set; }
|
public SwitchParameter ExcludePing { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 11, HelpMessage = "Associated device ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 12)]
|
|
||||||
public string? DeviceId { get; set; }
|
public string? DeviceId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 12, HelpMessage = "Port information.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 13)]
|
|
||||||
public string? Port { get; set; }
|
public string? Port { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Custom fields as a hashtable or PSObject.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true)]
|
|
||||||
public object? CustomFields { get; set; }
|
public object? CustomFields { get; set; }
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string> { "first_free" };
|
var identifiers = new[] { "first_free" };
|
||||||
var body = new Dictionary<string, object>
|
var body = BuildRequestBody();
|
||||||
{
|
|
||||||
{ "subnetId", SubnetId }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Gateway.IsPresent)
|
var result = RequestHelper.InvokeRequest(
|
||||||
body["is_gateway"] = "1";
|
"POST", ApiController.Addresses, null, null, body, identifiers
|
||||||
if (!string.IsNullOrEmpty(Description))
|
).GetAwaiter().GetResult();
|
||||||
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();
|
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
var ip = result.ToString();
|
var ip = result.ToString();
|
||||||
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, new[] { "search", ip })
|
var address = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Addresses, ModelType.Address, null, null,
|
||||||
if (address != null)
|
new[] { "search", ip! }
|
||||||
{
|
).GetAwaiter().GetResult();
|
||||||
WriteObject(address);
|
|
||||||
}
|
WriteResult(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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>();
|
var body = new Dictionary<string, object>
|
||||||
if (customFields is PSObject psobj)
|
|
||||||
{
|
{
|
||||||
foreach (var prop in psobj.Properties)
|
["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))
|
||||||
{
|
{
|
||||||
dict[prop.Name] = prop.Value ?? new object();
|
body[kvp.Key] = kvp.Value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (customFields is Dictionary<string, object> dictObj)
|
return body;
|
||||||
{
|
|
||||||
return dictObj;
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new phpIPAM API session.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.New, "Session", DefaultParameterSetName = "Credentials")]
|
[Cmdlet(VerbsCommon.New, "Session", DefaultParameterSetName = "Credentials")]
|
||||||
public class NewSessionCmdlet : PSCmdlet
|
[OutputType(typeof(Session))]
|
||||||
|
public class NewSessionCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0)]
|
Position = 0,
|
||||||
|
HelpMessage = "The phpIPAM server URL (must start with http:// or https://).")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
[ValidatePattern("^https?://")]
|
[ValidatePattern("^https?://")]
|
||||||
public string URL { get; set; } = string.Empty;
|
public string URL { get; set; } = string.Empty;
|
||||||
@@ -21,7 +25,8 @@ public class NewSessionCmdlet : PSCmdlet
|
|||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 1)]
|
Position = 1,
|
||||||
|
HelpMessage = "The API application ID configured in phpIPAM.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string AppID { get; set; } = string.Empty;
|
public string AppID { get; set; } = string.Empty;
|
||||||
|
|
||||||
@@ -30,7 +35,8 @@ public class NewSessionCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 2,
|
Position = 2,
|
||||||
ParameterSetName = "Credentials")]
|
ParameterSetName = "Credentials",
|
||||||
|
HelpMessage = "The credentials (username and password) for authentication.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public PSCredential? Credentials { get; set; }
|
public PSCredential? Credentials { get; set; }
|
||||||
|
|
||||||
@@ -39,7 +45,8 @@ public class NewSessionCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 2,
|
Position = 2,
|
||||||
ParameterSetName = "Token")]
|
ParameterSetName = "Token",
|
||||||
|
HelpMessage = "The static API token for authentication.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string? Token { get; set; }
|
public string? Token { get; set; }
|
||||||
|
|
||||||
@@ -47,7 +54,8 @@ public class NewSessionCmdlet : PSCmdlet
|
|||||||
Mandatory = false,
|
Mandatory = false,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 3)]
|
Position = 3,
|
||||||
|
HelpMessage = "If specified, SSL certificate errors will be ignored.")]
|
||||||
public SwitchParameter IgnoreSSL { get; set; }
|
public SwitchParameter IgnoreSSL { get; set; }
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
@@ -55,9 +63,10 @@ public class NewSessionCmdlet : PSCmdlet
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Session session;
|
Session session;
|
||||||
|
|
||||||
if (ParameterSetName == "Credentials" && Credentials != null)
|
if (ParameterSetName == "Credentials" && Credentials != null)
|
||||||
{
|
{
|
||||||
session = SessionManager.CreateSessionWithCredentials(
|
session = SessionManager.CreateSessionWithCredentialsAsync(
|
||||||
URL,
|
URL,
|
||||||
AppID,
|
AppID,
|
||||||
Credentials,
|
Credentials,
|
||||||
@@ -70,12 +79,14 @@ public class NewSessionCmdlet : PSCmdlet
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Invalid parameter set");
|
throw new ArgumentException("Invalid parameter set. Provide either Credentials or Token.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteObject(session);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteError(new ErrorRecord(ex, "NewSessionError", ErrorCategory.InvalidOperation, null));
|
WriteError(new ErrorRecord(ex, "NewSessionError", ErrorCategory.AuthenticationError, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net;
|
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new subnet in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.New, "Subnet")]
|
[Cmdlet(VerbsCommon.New, "Subnet")]
|
||||||
[OutputType(typeof(Subnetwork))]
|
[OutputType(typeof(Subnetwork))]
|
||||||
public class NewSubnetCmdlet : PSCmdlet
|
public class NewSubnetCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = 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}$")]
|
[ValidatePattern(@"^\d+\.\d+\.\d+\.\d+/\d{1,2}$")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public string CIDR { get; set; } = string.Empty;
|
public string CIDR { get; set; } = string.Empty;
|
||||||
@@ -23,187 +26,79 @@ public class NewSubnetCmdlet : PSCmdlet
|
|||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 1)]
|
Position = 1,
|
||||||
|
HelpMessage = "The section ID to create the subnet in.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int SectionId { get; set; }
|
public int SectionId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 2, HelpMessage = "Description for the subnet.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 2)]
|
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 3, HelpMessage = "VLAN ID to associate.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 3)]
|
|
||||||
public int? VlanId { get; set; }
|
public int? VlanId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 4, HelpMessage = "VRF ID to associate.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 4)]
|
|
||||||
public int? VrfId { get; set; }
|
public int? VrfId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 5, HelpMessage = "Master subnet ID for hierarchy.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 5)]
|
|
||||||
public int? MasterSubnetId { get; set; }
|
public int? MasterSubnetId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 6, HelpMessage = "Nameserver ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 6)]
|
|
||||||
public int? NameserverId { get; set; }
|
public int? NameserverId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 7, HelpMessage = "Show subnet name.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 7)]
|
|
||||||
public SwitchParameter ShowName { get; set; }
|
public SwitchParameter ShowName { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 8, HelpMessage = "Enable recursive DNS.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 8)]
|
|
||||||
public SwitchParameter DNSRecursive { get; set; }
|
public SwitchParameter DNSRecursive { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 9, HelpMessage = "Enable DNS records.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 9)]
|
|
||||||
public SwitchParameter DNSRecords { get; set; }
|
public SwitchParameter DNSRecords { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 10, HelpMessage = "Allow IP requests.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 10)]
|
|
||||||
public SwitchParameter AllowRequests { get; set; }
|
public SwitchParameter AllowRequests { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 11, HelpMessage = "Scan agent ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 11)]
|
|
||||||
public int? ScanAgentId { get; set; }
|
public int? ScanAgentId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 12, HelpMessage = "Enable subnet discovery.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 12)]
|
|
||||||
public SwitchParameter DiscoverSubnet { get; set; }
|
public SwitchParameter DiscoverSubnet { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 13, HelpMessage = "Mark subnet as full.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 12)]
|
|
||||||
public SwitchParameter IsFull { get; set; }
|
public SwitchParameter IsFull { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 14, HelpMessage = "Tag ID for the subnet.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 12)]
|
|
||||||
public int? TagId { get; set; }
|
public int? TagId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 15, HelpMessage = "Usage threshold percentage (1-100).")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 13)]
|
|
||||||
[ValidateRange(1, 100)]
|
[ValidateRange(1, 100)]
|
||||||
public int? Threshold { get; set; }
|
public int? Threshold { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, Position = 16, HelpMessage = "Location ID.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 14)]
|
|
||||||
public int? LocationId { get; set; }
|
public int? LocationId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Custom fields as a hashtable or PSObject.")]
|
||||||
Mandatory = false,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
Position = 15)]
|
|
||||||
public object? CustomFields { get; set; }
|
public object? CustomFields { get; set; }
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var parts = CIDR.Split('/');
|
var body = BuildRequestBody();
|
||||||
var body = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "subnet", parts[0] },
|
|
||||||
{ "mask", parts[1] },
|
|
||||||
{ "sectionId", SectionId }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Description))
|
var result = RequestHelper.InvokeRequest(
|
||||||
body["description"] = Description;
|
"POST", ApiController.Subnets, null, null, body
|
||||||
if (VlanId.HasValue)
|
).GetAwaiter().GetResult();
|
||||||
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();
|
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
// Get the created subnet
|
// Get the created subnet
|
||||||
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, new[] { "cidr", CIDR })
|
var subnet = RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null,
|
||||||
if (subnet != null)
|
new[] { "cidr", CIDR }
|
||||||
{
|
).GetAwaiter().GetResult();
|
||||||
WriteObject(subnet);
|
|
||||||
}
|
WriteResult(subnet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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>();
|
var parts = CIDR.Split('/');
|
||||||
if (customFields is PSObject psobj)
|
var body = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
foreach (var prop in psobj.Properties)
|
["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))
|
||||||
{
|
{
|
||||||
dict[prop.Name] = prop.Value ?? new object();
|
body[kvp.Key] = kvp.Value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (customFields is Dictionary<string, object> dictObj)
|
return body;
|
||||||
{
|
|
||||||
return dictObj;
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,31 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
[Cmdlet(VerbsCommon.Remove, "Address", DefaultParameterSetName = "ByID")]
|
/// <summary>
|
||||||
public class RemoveAddressCmdlet : PSCmdlet
|
/// 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(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
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]
|
[ValidateNotNullOrEmpty]
|
||||||
public Address? AddressObject { get; set; }
|
public Address? AddressObject { get; set; }
|
||||||
|
|
||||||
@@ -29,19 +33,17 @@ public class RemoveAddressCmdlet : PSCmdlet
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int addressId;
|
var addressId = ParameterSetName == "ById" ? Id : AddressObject!.Id;
|
||||||
if (ParameterSetName == "ByID")
|
var identifiers = new[] { addressId.ToString() };
|
||||||
{
|
|
||||||
addressId = Id!.Value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addressId = AddressObject!.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
var identifiers = new List<string> { addressId.ToString() };
|
if (ShouldProcess($"Address ID: {addressId}", "Remove"))
|
||||||
RequestHelper.InvokeRequest("DELETE", controllers.addresses, null, null, null, identifiers.ToArray())
|
{
|
||||||
.GetAwaiter().GetResult();
|
RequestHelper.InvokeRequest(
|
||||||
|
"DELETE", ApiController.Addresses, null, null, null, identifiers
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
WriteVerbose($"Address {addressId} removed successfully.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an existing IP address entry in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Set, "Address", DefaultParameterSetName = "ById")]
|
[Cmdlet(VerbsCommon.Set, "Address", DefaultParameterSetName = "ById")]
|
||||||
[OutputType(typeof(Address))]
|
[OutputType(typeof(Address))]
|
||||||
public class SetAddressCmdlet : PSCmdlet
|
public class SetAddressCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ById")]
|
ParameterSetName = "ById",
|
||||||
|
HelpMessage = "The address ID to update.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
@@ -23,142 +27,72 @@ public class SetAddressCmdlet : PSCmdlet
|
|||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0,
|
Position = 0,
|
||||||
ParameterSetName = "ByAddressObject")]
|
ParameterSetName = "ByAddressObject",
|
||||||
|
HelpMessage = "The address object to update.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public Address? AddressObject { get; set; }
|
public Address? AddressObject { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 1, HelpMessage = "Set as gateway address.")]
|
||||||
Position = 1,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
ParameterSetName = "ById")]
|
|
||||||
public bool? Gateway { get; set; }
|
public bool? Gateway { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 2, HelpMessage = "Description for the address.")]
|
||||||
Position = 2,
|
|
||||||
ValueFromPipeline = true,
|
|
||||||
ValueFromPipelineByPropertyName = true,
|
|
||||||
ParameterSetName = "ById")]
|
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 3, HelpMessage = "Hostname for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 3)]
|
|
||||||
public string? Hostname { get; set; }
|
public string? Hostname { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 4, HelpMessage = "MAC address.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 4)]
|
|
||||||
public string? MAC { get; set; }
|
public string? MAC { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 5, HelpMessage = "Owner of the address.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 5)]
|
|
||||||
public string? Owner { get; set; }
|
public string? Owner { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 6, HelpMessage = "Tag ID for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 6)]
|
|
||||||
public int? TagId { get; set; }
|
public int? TagId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 7, HelpMessage = "Ignore PTR record generation.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 7)]
|
|
||||||
public bool? PTRIgnore { get; set; }
|
public bool? PTRIgnore { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 8, HelpMessage = "PTR record ID.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 8)]
|
|
||||||
public int? PTRId { get; set; }
|
public int? PTRId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 9, HelpMessage = "Note for the address.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 9)]
|
|
||||||
public string? Note { get; set; }
|
public string? Note { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 10, HelpMessage = "Exclude from ping scanning.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 10)]
|
|
||||||
public bool? ExcludePing { get; set; }
|
public bool? ExcludePing { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 11, HelpMessage = "Associated device ID.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 11)]
|
|
||||||
public int? DeviceId { get; set; }
|
public int? DeviceId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Position = 12, HelpMessage = "Port information.")]
|
||||||
Mandatory = false,
|
|
||||||
Position = 12)]
|
|
||||||
public string? Port { get; set; }
|
public string? Port { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(HelpMessage = "Custom fields as a hashtable or PSObject.")]
|
||||||
Mandatory = false)]
|
|
||||||
public object? CustomFields { get; set; }
|
public object? CustomFields { get; set; }
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int addressId;
|
var addressId = ParameterSetName == "ById" ? Id!.Value : AddressObject!.Id;
|
||||||
if (ParameterSetName == "ById")
|
var identifiers = new[] { addressId.ToString() };
|
||||||
{
|
var body = BuildRequestBody();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RequestHelper.InvokeRequest("PATCH", controllers.addresses, null, null, body, identifiers.ToArray())
|
RequestHelper.InvokeRequest(
|
||||||
.GetAwaiter().GetResult();
|
"PATCH", ApiController.Addresses, null, null, body, identifiers
|
||||||
|
).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
var address = RequestHelper.InvokeRequest("GET", controllers.addresses, types.Address, null, null, identifiers.ToArray())
|
// Always return the updated address
|
||||||
.GetAwaiter().GetResult();
|
var address = RequestHelper.InvokeRequest(
|
||||||
if (address != null)
|
"GET", ApiController.Addresses, ModelType.Address, null, null, identifiers
|
||||||
{
|
).GetAwaiter().GetResult();
|
||||||
WriteObject(address);
|
|
||||||
}
|
WriteResult(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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>();
|
var body = new Dictionary<string, object>();
|
||||||
if (customFields is PSObject psobj)
|
|
||||||
|
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)
|
body[kvp.Key] = kvp.Value;
|
||||||
{
|
}
|
||||||
dict[prop.Name] = prop.Value ?? new object();
|
|
||||||
}
|
return body;
|
||||||
}
|
|
||||||
else if (customFields is Dictionary<string, object> dictObj)
|
|
||||||
{
|
|
||||||
return dictObj;
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,143 +1,91 @@
|
|||||||
namespace PS.IPAM.Cmdlets;
|
namespace PS.IPAM.Cmdlets;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using PS.IPAM;
|
|
||||||
using PS.IPAM.Helpers;
|
using PS.IPAM.Helpers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates an existing subnet in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Cmdlet(VerbsCommon.Set, "Subnet")]
|
[Cmdlet(VerbsCommon.Set, "Subnet")]
|
||||||
[OutputType(typeof(Subnetwork))]
|
[OutputType(typeof(Subnetwork))]
|
||||||
public class SetSubnetCmdlet : PSCmdlet
|
public class SetSubnetCmdlet : BaseCmdlet
|
||||||
{
|
{
|
||||||
[Parameter(
|
[Parameter(
|
||||||
Mandatory = true,
|
Mandatory = true,
|
||||||
ValueFromPipeline = true,
|
ValueFromPipeline = true,
|
||||||
ValueFromPipelineByPropertyName = true,
|
ValueFromPipelineByPropertyName = true,
|
||||||
Position = 0)]
|
Position = 0,
|
||||||
|
HelpMessage = "The subnet ID to update.")]
|
||||||
[ValidateNotNullOrEmpty]
|
[ValidateNotNullOrEmpty]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Description for the subnet.")]
|
||||||
Mandatory = false)]
|
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "VLAN ID to associate.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? VlanId { get; set; }
|
public int? VlanId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "VRF ID to associate.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? VrfId { get; set; }
|
public int? VrfId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Master subnet ID for hierarchy.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? MasterSubnetId { get; set; }
|
public int? MasterSubnetId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Nameserver ID.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? NameserverId { get; set; }
|
public int? NameserverId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Show subnet name.")]
|
||||||
Mandatory = false)]
|
|
||||||
public SwitchParameter ShowName { get; set; }
|
public SwitchParameter ShowName { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Enable recursive DNS.")]
|
||||||
Mandatory = false)]
|
|
||||||
public SwitchParameter DNSRecursive { get; set; }
|
public SwitchParameter DNSRecursive { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Enable DNS records.")]
|
||||||
Mandatory = false)]
|
|
||||||
public SwitchParameter DNSRecords { get; set; }
|
public SwitchParameter DNSRecords { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Allow IP requests.")]
|
||||||
Mandatory = false)]
|
|
||||||
public SwitchParameter AllowRequests { get; set; }
|
public SwitchParameter AllowRequests { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Scan agent ID.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? ScanAgentId { get; set; }
|
public int? ScanAgentId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Enable subnet discovery.")]
|
||||||
Mandatory = false)]
|
|
||||||
public SwitchParameter DiscoverSubnet { get; set; }
|
public SwitchParameter DiscoverSubnet { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Mark subnet as full.")]
|
||||||
Mandatory = false)]
|
|
||||||
public SwitchParameter IsFull { get; set; }
|
public SwitchParameter IsFull { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Tag ID for the subnet.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? TagId { get; set; }
|
public int? TagId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Usage threshold percentage (1-100).")]
|
||||||
Mandatory = false)]
|
|
||||||
[ValidateRange(1, 100)]
|
[ValidateRange(1, 100)]
|
||||||
public int? Threshold { get; set; }
|
public int? Threshold { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Location ID.")]
|
||||||
Mandatory = false)]
|
|
||||||
public int? LocationId { get; set; }
|
public int? LocationId { get; set; }
|
||||||
|
|
||||||
[Parameter(
|
[Parameter(Mandatory = false, HelpMessage = "Custom fields as a hashtable or PSObject.")]
|
||||||
Mandatory = false)]
|
|
||||||
public object? CustomFields { get; set; }
|
public object? CustomFields { get; set; }
|
||||||
|
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var identifiers = new List<string> { Id.ToString() };
|
var identifiers = new[] { Id.ToString() };
|
||||||
var body = new Dictionary<string, object>();
|
var body = BuildRequestBody();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Description))
|
RequestHelper.InvokeRequest(
|
||||||
body["description"] = Description;
|
"PATCH", ApiController.Subnets, null, null, body, identifiers
|
||||||
if (VlanId.HasValue)
|
).GetAwaiter().GetResult();
|
||||||
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 subnet = RequestHelper.InvokeRequest(
|
||||||
{
|
"GET", ApiController.Subnets, ModelType.Subnetwork, null, null, identifiers
|
||||||
var customDict = ConvertCustomFields(CustomFields);
|
).GetAwaiter().GetResult();
|
||||||
foreach (var kvp in customDict)
|
|
||||||
{
|
|
||||||
body[kvp.Key] = kvp.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestHelper.InvokeRequest("PATCH", controllers.subnets, null, null, body, identifiers.ToArray())
|
WriteResult(subnet);
|
||||||
.GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
var subnet = RequestHelper.InvokeRequest("GET", controllers.subnets, types.Subnetwork, null, null, identifiers.ToArray())
|
|
||||||
.GetAwaiter().GetResult();
|
|
||||||
if (subnet != null)
|
|
||||||
{
|
|
||||||
WriteObject(subnet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
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>();
|
var body = new Dictionary<string, object>();
|
||||||
if (customFields is PSObject psobj)
|
|
||||||
|
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)
|
body[kvp.Key] = kvp.Value;
|
||||||
{
|
}
|
||||||
dict[prop.Name] = prop.Value ?? new object();
|
|
||||||
}
|
return body;
|
||||||
}
|
|
||||||
else if (customFields is Dictionary<string, object> dictObj)
|
|
||||||
{
|
|
||||||
return dictObj;
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
namespace PS.IPAM.Helpers;
|
namespace PS.IPAM.Helpers;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,89 +10,46 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PS.IPAM;
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper class for making HTTP requests to the phpIPAM API.
|
||||||
|
/// </summary>
|
||||||
public static class RequestHelper
|
public static class RequestHelper
|
||||||
{
|
{
|
||||||
// Handler for testing - allows injecting a mock HTTP handler
|
/// <summary>
|
||||||
|
/// Handler for testing - allows injecting a mock HTTP handler.
|
||||||
|
/// </summary>
|
||||||
public static HttpMessageHandler? TestHttpHandler { get; set; }
|
public static HttpMessageHandler? TestHttpHandler { get; set; }
|
||||||
|
|
||||||
public static async Task<object?> InvokeRequest(
|
/// <summary>
|
||||||
string method,
|
/// Invokes an HTTP request to the phpIPAM API.
|
||||||
controllers controller,
|
/// </summary>
|
||||||
types? type = null,
|
/// <param name="method">The HTTP method (GET, POST, PATCH, DELETE).</param>
|
||||||
subcontrollers? subController = null,
|
/// <param name="controller">The API controller to call.</param>
|
||||||
|
/// <param name="modelType">The expected model type for response conversion.</param>
|
||||||
|
/// <param name="subController">Optional sub-controller for nested endpoints.</param>
|
||||||
|
/// <param name="parameters">Optional request body parameters.</param>
|
||||||
|
/// <param name="identifiers">Optional path identifiers.</param>
|
||||||
|
/// <param name="ignoreSsl">Whether to ignore SSL certificate errors.</param>
|
||||||
|
/// <returns>The deserialized response data, or null if not found.</returns>
|
||||||
|
public static async Task<object?> InvokeRequestAsync(
|
||||||
|
HttpMethod method,
|
||||||
|
ApiController controller,
|
||||||
|
ModelType? modelType = null,
|
||||||
|
ApiSubController? subController = null,
|
||||||
object? parameters = null,
|
object? parameters = null,
|
||||||
string[]? identifiers = null,
|
string[]? identifiers = null,
|
||||||
bool ignoreSsl = false)
|
bool ignoreSsl = false)
|
||||||
{
|
{
|
||||||
var tokenStatus = SessionManager.TestSession();
|
EnsureValidSession();
|
||||||
if (tokenStatus == "NoToken")
|
|
||||||
{
|
|
||||||
throw new Exception("No session available!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokenStatus == "Expired")
|
var session = SessionManager.CurrentSession!;
|
||||||
{
|
var uri = BuildUri(session, controller, subController, identifiers);
|
||||||
await UpdateSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
var session = SessionManager.CurrentSession;
|
|
||||||
if (session == null)
|
|
||||||
{
|
|
||||||
throw new Exception("No session available!");
|
|
||||||
}
|
|
||||||
|
|
||||||
var uri = $"{session.URL}/api/{session.AppID}/{controller}";
|
|
||||||
if (subController != null)
|
|
||||||
{
|
|
||||||
uri += $"/{subController}";
|
|
||||||
}
|
|
||||||
if (identifiers != null && identifiers.Length > 0)
|
|
||||||
{
|
|
||||||
uri += $"/{string.Join("/", identifiers)}/";
|
|
||||||
}
|
|
||||||
|
|
||||||
using var client = SessionManager.CreateHttpClient(ignoreSsl, TestHttpHandler);
|
using var client = SessionManager.CreateHttpClient(ignoreSsl, TestHttpHandler);
|
||||||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
ConfigureClient(client, session);
|
||||||
|
|
||||||
switch (session.AuthType)
|
var response = await SendRequestAsync(client, method, uri, parameters);
|
||||||
{
|
|
||||||
case AuthType.credentials:
|
|
||||||
client.DefaultRequestHeaders.Add("token", session.Token);
|
|
||||||
break;
|
|
||||||
case AuthType.token:
|
|
||||||
client.DefaultRequestHeaders.Add("phpipam-token", session.Token);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpResponseMessage? response = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (method == "GET")
|
|
||||||
{
|
|
||||||
response = await client.GetAsync(uri);
|
|
||||||
}
|
|
||||||
else if (method == "POST")
|
|
||||||
{
|
|
||||||
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
|
||||||
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
|
||||||
response = await client.PostAsync(uri, content);
|
|
||||||
}
|
|
||||||
else if (method == "PATCH")
|
|
||||||
{
|
|
||||||
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
|
||||||
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
|
||||||
var request = new HttpRequestMessage(new HttpMethod("PATCH"), uri)
|
|
||||||
{
|
|
||||||
Content = content
|
|
||||||
};
|
|
||||||
response = await client.SendAsync(request);
|
|
||||||
}
|
|
||||||
else if (method == "DELETE")
|
|
||||||
{
|
|
||||||
response = await client.DeleteAsync(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response == null)
|
if (response == null)
|
||||||
{
|
{
|
||||||
@@ -114,30 +72,197 @@ public static class RequestHelper
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ParseResponse(responseContent, modelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overload for backward compatibility using string method names.
|
||||||
|
/// </summary>
|
||||||
|
public static Task<object?> InvokeRequest(
|
||||||
|
string method,
|
||||||
|
ApiController controller,
|
||||||
|
ModelType? modelType = null,
|
||||||
|
ApiSubController? subController = null,
|
||||||
|
object? parameters = null,
|
||||||
|
string[]? identifiers = null,
|
||||||
|
bool ignoreSsl = false)
|
||||||
|
{
|
||||||
|
var httpMethod = method.ToUpperInvariant() switch
|
||||||
|
{
|
||||||
|
"GET" => HttpMethod.Get,
|
||||||
|
"POST" => HttpMethod.Post,
|
||||||
|
"PATCH" => new HttpMethod("PATCH"),
|
||||||
|
"DELETE" => HttpMethod.Delete,
|
||||||
|
"PUT" => HttpMethod.Put,
|
||||||
|
_ => throw new ArgumentException($"Unsupported HTTP method: {method}", nameof(method))
|
||||||
|
};
|
||||||
|
|
||||||
|
return InvokeRequestAsync(httpMethod, controller, modelType, subController, parameters, identifiers, ignoreSsl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Refreshes an expired session.
|
||||||
|
/// </summary>
|
||||||
|
public static async Task RefreshSessionAsync()
|
||||||
|
{
|
||||||
|
var session = SessionManager.CurrentSession;
|
||||||
|
if (session == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No session available!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var status = SessionManager.GetSessionStatus();
|
||||||
|
if (status == SessionStatus.Valid)
|
||||||
|
{
|
||||||
|
// Just refresh the token
|
||||||
|
await InvokeRequestAsync(new HttpMethod("PATCH"), ApiController.User);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == SessionStatus.Expired && session.Credentials is PSCredential creds)
|
||||||
|
{
|
||||||
|
await SessionManager.CreateSessionWithCredentialsAsync(
|
||||||
|
session.URL,
|
||||||
|
session.AppID,
|
||||||
|
creds,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureValidSession()
|
||||||
|
{
|
||||||
|
var status = SessionManager.GetSessionStatus();
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case SessionStatus.NoSession:
|
||||||
|
throw new InvalidOperationException("No session available!");
|
||||||
|
|
||||||
|
case SessionStatus.Expired:
|
||||||
|
RefreshSessionAsync().GetAwaiter().GetResult();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string BuildUri(
|
||||||
|
Session session,
|
||||||
|
ApiController controller,
|
||||||
|
ApiSubController? subController,
|
||||||
|
string[]? identifiers)
|
||||||
|
{
|
||||||
|
var controllerName = GetControllerName(controller);
|
||||||
|
var uri = $"{session.URL}/api/{session.AppID}/{controllerName}";
|
||||||
|
|
||||||
|
if (subController.HasValue)
|
||||||
|
{
|
||||||
|
uri += $"/{GetSubControllerName(subController.Value)}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (identifiers is { Length: > 0 })
|
||||||
|
{
|
||||||
|
uri += $"/{string.Join("/", identifiers)}/";
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetControllerName(ApiController controller) => controller switch
|
||||||
|
{
|
||||||
|
ApiController.User => "user",
|
||||||
|
ApiController.Vlan => "vlan",
|
||||||
|
ApiController.Subnets => "subnets",
|
||||||
|
ApiController.Addresses => "addresses",
|
||||||
|
ApiController.Sections => "sections",
|
||||||
|
ApiController.Vrf => "vrf",
|
||||||
|
ApiController.L2Domains => "l2domains",
|
||||||
|
ApiController.Tools => "tools",
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(controller))
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string GetSubControllerName(ApiSubController subController) => subController switch
|
||||||
|
{
|
||||||
|
ApiSubController.Nameservers => "nameservers",
|
||||||
|
ApiSubController.Tags => "tags",
|
||||||
|
ApiSubController.Devices => "devices",
|
||||||
|
ApiSubController.DeviceTypes => "device_types",
|
||||||
|
ApiSubController.Vlans => "vlans",
|
||||||
|
ApiSubController.Vrfs => "vrfs",
|
||||||
|
ApiSubController.ScanAgents => "scanagents",
|
||||||
|
ApiSubController.Locations => "locations",
|
||||||
|
ApiSubController.Nat => "nat",
|
||||||
|
ApiSubController.Racks => "racks",
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(subController))
|
||||||
|
};
|
||||||
|
|
||||||
|
private static void ConfigureClient(HttpClient client, Session session)
|
||||||
|
{
|
||||||
|
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
|
||||||
|
switch (session.AuthType)
|
||||||
|
{
|
||||||
|
case AuthType.Credentials:
|
||||||
|
client.DefaultRequestHeaders.Add("token", session.Token);
|
||||||
|
break;
|
||||||
|
case AuthType.Token:
|
||||||
|
client.DefaultRequestHeaders.Add("phpipam-token", session.Token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<HttpResponseMessage?> SendRequestAsync(
|
||||||
|
HttpClient client,
|
||||||
|
HttpMethod method,
|
||||||
|
string uri,
|
||||||
|
object? parameters)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (method == HttpMethod.Get)
|
||||||
|
{
|
||||||
|
return await client.GetAsync(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method == HttpMethod.Delete)
|
||||||
|
{
|
||||||
|
return await client.DeleteAsync(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonContent = parameters != null ? JsonConvert.SerializeObject(parameters) : "{}";
|
||||||
|
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
if (method == HttpMethod.Post)
|
||||||
|
{
|
||||||
|
return await client.PostAsync(uri, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PATCH, PUT, etc.
|
||||||
|
var request = new HttpRequestMessage(method, uri) { Content = content };
|
||||||
|
return await client.SendAsync(request);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex) when (ex.Message.Contains("404"))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object? ParseResponse(string responseContent, ModelType? modelType)
|
||||||
|
{
|
||||||
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(responseContent);
|
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(responseContent);
|
||||||
if (jsonResponse == null)
|
if (jsonResponse == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.HasValue)
|
if (!modelType.HasValue)
|
||||||
{
|
{
|
||||||
return ConvertToTypedObjects(jsonResponse, type.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return jsonResponse.data;
|
return jsonResponse.data;
|
||||||
}
|
}
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
return ConvertToTypedObjects(jsonResponse, modelType.Value);
|
||||||
if (ex.Message.Contains("404"))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object? ConvertToTypedObjects(dynamic jsonResponse, types type)
|
private static object? ConvertToTypedObjects(dynamic jsonResponse, ModelType modelType)
|
||||||
{
|
{
|
||||||
if (jsonResponse?.data == null)
|
if (jsonResponse?.data == null)
|
||||||
{
|
{
|
||||||
@@ -147,228 +272,170 @@ public static class RequestHelper
|
|||||||
var data = jsonResponse.data;
|
var data = jsonResponse.data;
|
||||||
if (data is JArray array)
|
if (data is JArray array)
|
||||||
{
|
{
|
||||||
return array.Select(item => ConvertSingleObject(item, type)).ToList();
|
return array.Select(item => ConvertSingleObject(item, modelType)).ToList();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ConvertSingleObject(data, type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static object? ConvertSingleObject(dynamic item, types type)
|
return ConvertSingleObject(data, modelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object? ConvertSingleObject(dynamic item, ModelType modelType)
|
||||||
{
|
{
|
||||||
var jobject = item as JObject;
|
if (item is not JObject jobject)
|
||||||
if (jobject == null)
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var customFields = ExtractCustomFields(jobject);
|
||||||
|
|
||||||
|
return modelType switch
|
||||||
|
{
|
||||||
|
ModelType.Address => CreateAddress(jobject, customFields),
|
||||||
|
ModelType.Vlan => CreateVlan(jobject, customFields),
|
||||||
|
ModelType.Subnetwork => CreateSubnetwork(jobject, customFields),
|
||||||
|
ModelType.Vrf => CreateVrf(jobject, customFields),
|
||||||
|
ModelType.Section => CreateSection(jobject),
|
||||||
|
ModelType.Tag => CreateTag(jobject),
|
||||||
|
ModelType.Nameserver => CreateNameserver(jobject),
|
||||||
|
ModelType.Domain => CreateDomain(jobject),
|
||||||
|
_ => jobject.ToObject<object>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<string, object>? ExtractCustomFields(JObject jobject)
|
||||||
|
{
|
||||||
var customFields = new Dictionary<string, object>();
|
var customFields = new Dictionary<string, object>();
|
||||||
foreach (var prop in jobject.Properties())
|
foreach (var prop in jobject.Properties().Where(p => p.Name.StartsWith("custom_")))
|
||||||
{
|
{
|
||||||
if (prop.Name.StartsWith("custom_"))
|
customFields[prop.Name] = prop.Value?.ToObject<object>() ?? string.Empty;
|
||||||
{
|
|
||||||
customFields[prop.Name] = prop.Value?.ToObject<object>() ?? new object();
|
|
||||||
}
|
}
|
||||||
|
return customFields.Count > 0 ? customFields : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type)
|
#region Model Factory Methods
|
||||||
{
|
|
||||||
case types.Address:
|
|
||||||
return CreateAddress(jobject, customFields);
|
|
||||||
case types.Vlan:
|
|
||||||
return CreateVlan(jobject, customFields);
|
|
||||||
case types.Subnetwork:
|
|
||||||
return CreateSubnetwork(jobject, customFields);
|
|
||||||
case types.Vrf:
|
|
||||||
return CreateVrf(jobject, customFields);
|
|
||||||
case types.Section:
|
|
||||||
return CreateSection(jobject);
|
|
||||||
case types.Tag:
|
|
||||||
return CreateTag(jobject);
|
|
||||||
case types.Nameserver:
|
|
||||||
return CreateNameserver(jobject);
|
|
||||||
case types.Domain:
|
|
||||||
return CreateDomain(jobject);
|
|
||||||
default:
|
|
||||||
return jobject.ToObject<object>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Address CreateAddress(JObject jobject, Dictionary<string, object> customFields)
|
private static Address CreateAddress(JObject obj, Dictionary<string, object>? customFields) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
return new Address(
|
obj["subnetId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["ip"]?.ToString() ?? "",
|
||||||
jobject["subnetId"]?.ToObject<int>() ?? 0,
|
obj["is_gateway"]?.ToObject<bool>() ?? false,
|
||||||
jobject["ip"]?.ToString() ?? "",
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["is_gateway"]?.ToObject<bool>() ?? false,
|
obj["hostname"]?.ToString() ?? "",
|
||||||
jobject["description"]?.ToString() ?? "",
|
obj["mac"]?.ToString() ?? "",
|
||||||
jobject["hostname"]?.ToString() ?? "",
|
obj["owner"]?.ToString() ?? "",
|
||||||
jobject["mac"]?.ToString() ?? "",
|
obj["tag"]?.ToObject<int>() ?? 0,
|
||||||
jobject["owner"]?.ToString() ?? "",
|
obj["deviceId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["tag"]?.ToObject<int>() ?? 0,
|
obj["location"]?.ToString() ?? "",
|
||||||
jobject["deviceId"]?.ToObject<int>() ?? 0,
|
obj["port"]?.ToString() ?? "",
|
||||||
jobject["location"]?.ToString() ?? "",
|
obj["note"]?.ToString() ?? "",
|
||||||
jobject["port"]?.ToString() ?? "",
|
obj["lastSeen"]?.ToObject<DateTime?>(),
|
||||||
jobject["note"]?.ToString() ?? "",
|
obj["excludePing"]?.ToObject<bool>() ?? false,
|
||||||
jobject["lastSeen"]?.ToObject<DateTime?>(),
|
obj["PTRignore"]?.ToObject<bool>() ?? false,
|
||||||
jobject["excludePing"]?.ToObject<bool>() ?? false,
|
obj["PTR"]?.ToObject<int>() ?? 0,
|
||||||
jobject["PTRignore"]?.ToObject<bool>() ?? false,
|
obj["firewallAddressObject"]?.ToString() ?? "",
|
||||||
jobject["PTR"]?.ToObject<int>() ?? 0,
|
obj["editDate"]?.ToObject<DateTime?>(),
|
||||||
jobject["firewallAddressObject"]?.ToString() ?? "",
|
obj["customer_id"]?.ToObject<int>() ?? 0,
|
||||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
customFields
|
||||||
jobject["customer_id"]?.ToObject<int>() ?? 0,
|
|
||||||
customFields.Count > 0 ? customFields : null
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Vlan CreateVlan(JObject jobject, Dictionary<string, object> customFields)
|
private static Vlan CreateVlan(JObject obj, Dictionary<string, object>? customFields) => new(
|
||||||
{
|
obj["vlanId"]?.ToObject<int>() ?? 0,
|
||||||
return new Vlan(
|
obj["domainId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["vlanId"]?.ToObject<int>() ?? 0,
|
obj["name"]?.ToString() ?? "",
|
||||||
jobject["domainId"]?.ToObject<int>() ?? 0,
|
obj["number"]?.ToObject<int>() ?? 0,
|
||||||
jobject["name"]?.ToString() ?? "",
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["number"]?.ToObject<int>() ?? 0,
|
obj["editDate"]?.ToObject<DateTime?>(),
|
||||||
jobject["description"]?.ToString() ?? "",
|
obj["customer_id"]?.ToObject<int>() ?? 0,
|
||||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
customFields
|
||||||
jobject["customer_id"]?.ToObject<int>() ?? 0,
|
|
||||||
customFields.Count > 0 ? customFields : null
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Subnetwork CreateSubnetwork(JObject jobject, Dictionary<string, object> customFields)
|
private static Subnetwork CreateSubnetwork(JObject obj, Dictionary<string, object>? customFields) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
var props = jobject.Properties().ToList();
|
obj["subnet"]?.ToString() ?? "",
|
||||||
return new Subnetwork(
|
obj["mask"]?.ToObject<int>() ?? 0,
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["sectionId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["subnet"]?.ToString() ?? "",
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["mask"]?.ToObject<int>() ?? 0,
|
obj["linked_subnet"]?.ToString() ?? "",
|
||||||
jobject["sectionId"]?.ToObject<int>() ?? 0,
|
obj["firewallAddressObject"]?.ToString() ?? "",
|
||||||
jobject["description"]?.ToString() ?? "",
|
obj["vrfId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["linked_subnet"]?.ToString() ?? "",
|
obj["masterSubnetId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["firewallAddressObject"]?.ToString() ?? "",
|
obj["allowRequests"]?.ToObject<bool>() ?? false,
|
||||||
jobject["vrfId"]?.ToObject<int>() ?? 0,
|
obj["vlanId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["masterSubnetId"]?.ToObject<int>() ?? 0,
|
obj["showName"]?.ToObject<bool>() ?? false,
|
||||||
jobject["allowRequests"]?.ToObject<bool>() ?? false,
|
obj["deviceId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["vlanId"]?.ToObject<int>() ?? 0,
|
obj["permissions"]?.ToString() ?? "",
|
||||||
jobject["showName"]?.ToObject<bool>() ?? false,
|
obj["pingSubnet"]?.ToObject<bool>() ?? false,
|
||||||
jobject["deviceId"]?.ToObject<int>() ?? 0,
|
obj["discoverSubnet"]?.ToObject<bool>() ?? false,
|
||||||
jobject["permissions"]?.ToString() ?? "",
|
obj["resolveDNS"]?.ToObject<bool>() ?? false,
|
||||||
jobject["pingSubnet"]?.ToObject<bool>() ?? false,
|
obj["DNSrecursive"]?.ToObject<bool>() ?? false,
|
||||||
jobject["discoverSubnet"]?.ToObject<bool>() ?? false,
|
obj["DNSrecords"]?.ToObject<bool>() ?? false,
|
||||||
jobject["resolveDNS"]?.ToObject<bool>() ?? false,
|
obj["nameserverId"]?.ToObject<int>() ?? 0,
|
||||||
jobject["DNSrecursive"]?.ToObject<bool>() ?? false,
|
obj["scanAgent"]?.ToObject<bool>() ?? false,
|
||||||
jobject["DNSrecords"]?.ToObject<bool>() ?? false,
|
obj["isFolder"]?.ToObject<bool>() ?? false,
|
||||||
jobject["nameserverId"]?.ToObject<int>() ?? 0,
|
obj["isFull"]?.ToObject<bool>() ?? false,
|
||||||
jobject["scanAgent"]?.ToObject<bool>() ?? false,
|
obj["isPool"]?.ToObject<bool>() ?? false,
|
||||||
jobject["isFolder"]?.ToObject<bool>() ?? false,
|
obj["state"]?.ToObject<int>() ?? 0,
|
||||||
jobject["isFull"]?.ToObject<bool>() ?? false,
|
obj["threshold"]?.ToObject<int>() ?? 0,
|
||||||
jobject["isPool"]?.ToObject<bool>() ?? false,
|
obj["location"]?.ToObject<int>() ?? 0,
|
||||||
jobject["state"]?.ToObject<int>() ?? 0,
|
obj["editDate"]?.ToObject<DateTime?>(),
|
||||||
jobject["threshold"]?.ToObject<int>() ?? 0,
|
obj["lastScan"]?.ToObject<DateTime?>(),
|
||||||
jobject["location"]?.ToObject<int>() ?? 0,
|
obj["lastDiscovery"]?.ToObject<DateTime?>(),
|
||||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
obj["calculation"]?.ToObject<object>() ?? new object(),
|
||||||
jobject["lastScan"]?.ToObject<DateTime?>(),
|
customFields
|
||||||
jobject["lastDiscovery"]?.ToObject<DateTime?>(),
|
|
||||||
jobject["calculation"]?.ToObject<object>() ?? new object(),
|
|
||||||
customFields.Count > 0 ? customFields : null
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Vrf CreateVrf(JObject jobject, Dictionary<string, object> customFields)
|
private static Vrf CreateVrf(JObject obj, Dictionary<string, object>? customFields) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
return new Vrf(
|
obj["name"]?.ToString() ?? "",
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["rd"]?.ToString() ?? "",
|
||||||
jobject["name"]?.ToString() ?? "",
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["rd"]?.ToString() ?? "",
|
obj["sections"]?.ToString() ?? "",
|
||||||
jobject["description"]?.ToString() ?? "",
|
obj["editDate"]?.ToObject<DateTime?>(),
|
||||||
jobject["sections"]?.ToString() ?? "",
|
customFields
|
||||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
|
||||||
customFields.Count > 0 ? customFields : null
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Section CreateSection(JObject jobject)
|
private static Section CreateSection(JObject obj) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
return new Section(
|
obj["name"]?.ToString() ?? "",
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["name"]?.ToString() ?? "",
|
obj["masterSection"]?.ToObject<int>() ?? 0,
|
||||||
jobject["description"]?.ToString() ?? "",
|
obj["permissions"]?.ToString() ?? "",
|
||||||
jobject["masterSection"]?.ToObject<int>() ?? 0,
|
obj["strictMode"]?.ToObject<bool>() ?? false,
|
||||||
jobject["permissions"]?.ToString() ?? "",
|
obj["subnetOrdering"]?.ToString() ?? "",
|
||||||
jobject["strictMode"]?.ToObject<bool>() ?? false,
|
obj["order"]?.ToObject<int>() ?? 0,
|
||||||
jobject["subnetOrdering"]?.ToString() ?? "",
|
obj["editDate"]?.ToObject<DateTime?>(),
|
||||||
jobject["order"]?.ToObject<int>() ?? 0,
|
obj["showSubnet"]?.ToObject<bool>() ?? false,
|
||||||
jobject["editDate"]?.ToObject<DateTime?>(),
|
obj["showVlan"]?.ToObject<bool>() ?? false,
|
||||||
jobject["showSubnet"]?.ToObject<bool>() ?? false,
|
obj["showVRF"]?.ToObject<bool>() ?? false,
|
||||||
jobject["showVlan"]?.ToObject<bool>() ?? false,
|
obj["showSupernetOnly"]?.ToObject<bool>() ?? false,
|
||||||
jobject["showVRF"]?.ToObject<bool>() ?? false,
|
obj["DNS"]?.ToObject<int>() ?? 0
|
||||||
jobject["showSupernetOnly"]?.ToObject<bool>() ?? false,
|
|
||||||
jobject["DNS"]?.ToObject<int>() ?? 0
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Tag CreateTag(JObject jobject)
|
private static Tag CreateTag(JObject obj) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
return new Tag(
|
obj["type"]?.ToString() ?? "",
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["showtag"]?.ToObject<bool>() ?? false,
|
||||||
jobject["type"]?.ToString() ?? "",
|
obj["bgcolor"]?.ToString() ?? "",
|
||||||
jobject["showtag"]?.ToObject<bool>() ?? false,
|
obj["fgcolor"]?.ToString() ?? "",
|
||||||
jobject["bgcolor"]?.ToString() ?? "",
|
obj["compress"]?.ToString() ?? "",
|
||||||
jobject["fgcolor"]?.ToString() ?? "",
|
obj["locked"]?.ToString() ?? "",
|
||||||
jobject["compress"]?.ToString() ?? "",
|
obj["updateTag"]?.ToObject<bool>() ?? false
|
||||||
jobject["locked"]?.ToString() ?? "",
|
|
||||||
jobject["updateTag"]?.ToObject<bool>() ?? false
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Nameserver CreateNameserver(JObject jobject)
|
private static Nameserver CreateNameserver(JObject obj) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
return new Nameserver(
|
obj["name"]?.ToString() ?? "",
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["nameservers"]?.ToString() ?? "",
|
||||||
jobject["name"]?.ToString() ?? "",
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["nameservers"]?.ToString() ?? "",
|
obj["permissions"]?.ToString() ?? "",
|
||||||
jobject["description"]?.ToString() ?? "",
|
obj["editDate"]?.ToObject<DateTime?>()
|
||||||
jobject["permissions"]?.ToString() ?? "",
|
|
||||||
jobject["editDate"]?.ToObject<DateTime?>()
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static Domain CreateDomain(JObject jobject)
|
private static Domain CreateDomain(JObject obj) => new(
|
||||||
{
|
obj["id"]?.ToObject<int>() ?? 0,
|
||||||
return new Domain(
|
obj["name"]?.ToString() ?? "",
|
||||||
jobject["id"]?.ToObject<int>() ?? 0,
|
obj["description"]?.ToString() ?? "",
|
||||||
jobject["name"]?.ToString() ?? "",
|
obj["sections"]?.ToString() ?? ""
|
||||||
jobject["description"]?.ToString() ?? "",
|
|
||||||
jobject["sections"]?.ToString() ?? ""
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task UpdateSession()
|
#endregion
|
||||||
{
|
|
||||||
var session = SessionManager.CurrentSession;
|
|
||||||
if (session == null)
|
|
||||||
{
|
|
||||||
throw new Exception("No session available!");
|
|
||||||
}
|
|
||||||
|
|
||||||
var tokenStatus = SessionManager.TestSession();
|
|
||||||
if (tokenStatus == "Valid")
|
|
||||||
{
|
|
||||||
// Just refresh the token
|
|
||||||
var result = await InvokeRequest("PATCH", controllers.user, null, null, null, null);
|
|
||||||
// Token refresh doesn't return expires in the same format, so we'll skip updating expires
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tokenStatus == "Expired" && session.Credentials is PSCredential creds)
|
|
||||||
{
|
|
||||||
await SessionManager.CreateSessionWithCredentials(
|
|
||||||
session.URL,
|
|
||||||
session.AppID,
|
|
||||||
creds,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,60 @@
|
|||||||
namespace PS.IPAM.Helpers;
|
namespace PS.IPAM.Helpers;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PS.IPAM;
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages phpIPAM API sessions including creation, validation, and lifecycle.
|
||||||
|
/// </summary>
|
||||||
public static class SessionManager
|
public static class SessionManager
|
||||||
{
|
{
|
||||||
private static Session? _currentSession;
|
private static Session? _currentSession;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current active session.
|
||||||
|
/// </summary>
|
||||||
public static Session? CurrentSession
|
public static Session? CurrentSession
|
||||||
{
|
{
|
||||||
get => _currentSession;
|
get => _currentSession;
|
||||||
set => _currentSession = value;
|
set => _currentSession = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string TestSession()
|
/// <summary>
|
||||||
|
/// Tests the current session status.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The session status indicating validity or issues.</returns>
|
||||||
|
public static SessionStatus GetSessionStatus()
|
||||||
{
|
{
|
||||||
if (_currentSession == null)
|
if (_currentSession == null)
|
||||||
{
|
{
|
||||||
return "NoToken";
|
return SessionStatus.NoSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_currentSession.Expires == null)
|
if (_currentSession.Expires == null)
|
||||||
{
|
{
|
||||||
return "Valid";
|
return SessionStatus.Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_currentSession.Expires < DateTime.Now)
|
return _currentSession.Expires < DateTime.Now
|
||||||
{
|
? SessionStatus.Expired
|
||||||
return "Expired";
|
: SessionStatus.Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Valid";
|
/// <summary>
|
||||||
}
|
/// Creates a new session using username/password credentials.
|
||||||
|
/// </summary>
|
||||||
public static async Task<Session> CreateSessionWithCredentials(
|
/// <param name="url">The phpIPAM server URL.</param>
|
||||||
|
/// <param name="appId">The API application ID.</param>
|
||||||
|
/// <param name="credentials">The PowerShell credential object.</param>
|
||||||
|
/// <param name="ignoreSsl">Whether to ignore SSL certificate errors.</param>
|
||||||
|
/// <returns>The created session.</returns>
|
||||||
|
public static async Task<Session> CreateSessionWithCredentialsAsync(
|
||||||
string url,
|
string url,
|
||||||
string appId,
|
string appId,
|
||||||
PSCredential credentials,
|
PSCredential credentials,
|
||||||
@@ -46,7 +62,7 @@ public static class SessionManager
|
|||||||
{
|
{
|
||||||
var uri = $"{url}/api/{appId}/user";
|
var uri = $"{url}/api/{appId}/user";
|
||||||
var auth = Convert.ToBase64String(
|
var auth = Convert.ToBase64String(
|
||||||
Encoding.UTF8.GetBytes($"{credentials.UserName}:{GetPassword(credentials)}"));
|
Encoding.UTF8.GetBytes($"{credentials.UserName}:{GetPasswordString(credentials)}"));
|
||||||
|
|
||||||
using var client = CreateHttpClient(ignoreSsl);
|
using var client = CreateHttpClient(ignoreSsl);
|
||||||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
@@ -58,14 +74,15 @@ public static class SessionManager
|
|||||||
|
|
||||||
if (jsonResponse?.success != true)
|
if (jsonResponse?.success != true)
|
||||||
{
|
{
|
||||||
throw new Exception(jsonResponse?.error?.ToString() ?? "Failed to create session");
|
throw new InvalidOperationException(
|
||||||
|
jsonResponse?.error?.ToString() ?? "Failed to create session");
|
||||||
}
|
}
|
||||||
|
|
||||||
var token = jsonResponse.data.token.ToString();
|
var token = jsonResponse.data.token.ToString();
|
||||||
var expires = DateTime.Parse(jsonResponse.data.expires.ToString());
|
var expires = DateTime.Parse(jsonResponse.data.expires.ToString());
|
||||||
|
|
||||||
_currentSession = new Session(
|
_currentSession = new Session(
|
||||||
AuthType.credentials,
|
AuthType.Credentials,
|
||||||
token,
|
token,
|
||||||
appId,
|
appId,
|
||||||
url,
|
url,
|
||||||
@@ -76,13 +93,17 @@ public static class SessionManager
|
|||||||
return _currentSession;
|
return _currentSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Session CreateSessionWithToken(
|
/// <summary>
|
||||||
string url,
|
/// Creates a new session using a static API token.
|
||||||
string appId,
|
/// </summary>
|
||||||
string token)
|
/// <param name="url">The phpIPAM server URL.</param>
|
||||||
|
/// <param name="appId">The API application ID.</param>
|
||||||
|
/// <param name="token">The API token.</param>
|
||||||
|
/// <returns>The created session.</returns>
|
||||||
|
public static Session CreateSessionWithToken(string url, string appId, string token)
|
||||||
{
|
{
|
||||||
_currentSession = new Session(
|
_currentSession = new Session(
|
||||||
AuthType.token,
|
AuthType.Token,
|
||||||
token,
|
token,
|
||||||
appId,
|
appId,
|
||||||
url,
|
url,
|
||||||
@@ -93,24 +114,20 @@ public static class SessionManager
|
|||||||
return _currentSession;
|
return _currentSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the current session and clears session data.
|
||||||
|
/// </summary>
|
||||||
public static void CloseSession()
|
public static void CloseSession()
|
||||||
{
|
{
|
||||||
_currentSession = null;
|
_currentSession = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetPassword(PSCredential credential)
|
/// <summary>
|
||||||
{
|
/// Creates an HttpClient with optional SSL bypass.
|
||||||
var ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(credential.Password);
|
/// </summary>
|
||||||
try
|
/// <param name="ignoreSsl">Whether to ignore SSL certificate errors.</param>
|
||||||
{
|
/// <param name="handler">Optional custom message handler for testing.</param>
|
||||||
return System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
|
/// <returns>A configured HttpClient instance.</returns>
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HttpClient CreateHttpClient(bool ignoreSsl = false, HttpMessageHandler? handler = null)
|
public static HttpClient CreateHttpClient(bool ignoreSsl = false, HttpMessageHandler? handler = null)
|
||||||
{
|
{
|
||||||
if (handler != null)
|
if (handler != null)
|
||||||
@@ -122,10 +139,27 @@ public static class SessionManager
|
|||||||
{
|
{
|
||||||
var sslHandler = new HttpClientHandler
|
var sslHandler = new HttpClientHandler
|
||||||
{
|
{
|
||||||
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
|
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||||
};
|
};
|
||||||
return new HttpClient(sslHandler);
|
return new HttpClient(sslHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HttpClient();
|
return new HttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts the plain text password from a PSCredential object.
|
||||||
|
/// </summary>
|
||||||
|
private static string GetPasswordString(PSCredential credential)
|
||||||
|
{
|
||||||
|
var ptr = Marshal.SecureStringToBSTR(credential.Password);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Marshal.PtrToStringBSTR(ptr);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Marshal.ZeroFreeBSTR(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +1,35 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an IP address entry in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Address {
|
public sealed record Address(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public int SubnetId { get; }
|
int SubnetId,
|
||||||
public string Ip { get; }
|
string Ip,
|
||||||
public bool IsGateway { get; }
|
bool IsGateway,
|
||||||
public string Description { get; }
|
string Description,
|
||||||
public string Hostname { get; }
|
string Hostname,
|
||||||
public string MAC { get; }
|
string MAC,
|
||||||
public string Owner { get; }
|
string Owner,
|
||||||
public int TagId { get; }
|
int TagId,
|
||||||
public int DeviceId { get; }
|
int DeviceId,
|
||||||
public string Location { get; }
|
string Location,
|
||||||
public string Port { get; }
|
string Port,
|
||||||
public string Note { get; }
|
string Note,
|
||||||
public DateTime? LastSeen { get; }
|
DateTime? LastSeen,
|
||||||
public bool ExcludePing { get; }
|
bool ExcludePing,
|
||||||
public bool PTRignore { get; }
|
bool PTRIgnore,
|
||||||
public int PTR { get; }
|
|
||||||
public string FirewallAddressObject { get; }
|
|
||||||
public DateTime? EditDate { get; }
|
|
||||||
public int CustomerId { get; }
|
|
||||||
public Object? ExtendedData { get; }
|
|
||||||
|
|
||||||
public Address(
|
|
||||||
int id,
|
|
||||||
int subnetId,
|
|
||||||
string ip,
|
|
||||||
bool is_gateway,
|
|
||||||
string description,
|
|
||||||
string hostname,
|
|
||||||
string mac,
|
|
||||||
string owner,
|
|
||||||
int tag,
|
|
||||||
int deviceId,
|
|
||||||
string location,
|
|
||||||
string port,
|
|
||||||
string note,
|
|
||||||
DateTime? lastSeen,
|
|
||||||
bool excludePing,
|
|
||||||
bool PTRignore,
|
|
||||||
int PTR,
|
int PTR,
|
||||||
string firewallAddressObject,
|
string FirewallAddressObject,
|
||||||
DateTime? editDate,
|
DateTime? EditDate,
|
||||||
int customer_id,
|
int CustomerId,
|
||||||
Object? extendedData
|
Dictionary<string, object>? ExtendedData = null
|
||||||
) {
|
)
|
||||||
this.Id = id;
|
{
|
||||||
this.SubnetId = subnetId;
|
public override string ToString() => Ip;
|
||||||
this.Ip = ip;
|
|
||||||
this.IsGateway = is_gateway;
|
|
||||||
this.Description = description;
|
|
||||||
this.Hostname = hostname;
|
|
||||||
this.MAC = mac;
|
|
||||||
this.Owner = owner;
|
|
||||||
this.TagId = tag;
|
|
||||||
this.DeviceId = deviceId;
|
|
||||||
this.Location = location;
|
|
||||||
this.Port = port;
|
|
||||||
this.Note = note;
|
|
||||||
this.LastSeen = lastSeen;
|
|
||||||
this.ExcludePing = excludePing;
|
|
||||||
this.PTRignore = PTRignore;
|
|
||||||
this.PTR = PTR;
|
|
||||||
this.FirewallAddressObject = firewallAddressObject;
|
|
||||||
this.EditDate = editDate;
|
|
||||||
this.CustomerId = customer_id;
|
|
||||||
this.ExtendedData = extendedData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return this.Ip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,27 +1,17 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an L2 domain in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Domain {
|
public sealed record Domain(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public string Name { get; }
|
string Name,
|
||||||
public string Description { get; }
|
string Description,
|
||||||
public string Sections { get; }
|
string Sections
|
||||||
|
)
|
||||||
public Domain (
|
|
||||||
int id,
|
|
||||||
string name,
|
|
||||||
string description,
|
|
||||||
string sections
|
|
||||||
) {
|
|
||||||
this.Id = id;
|
|
||||||
this.Name = name;
|
|
||||||
this.Description = description;
|
|
||||||
this.Sections = sections;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return this.Name;
|
public override string ToString() => Name;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a nameserver configuration in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Nameserver {
|
public sealed record Nameserver
|
||||||
|
{
|
||||||
public int Id { get; }
|
public int Id { get; }
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string[] NameServers { get; }
|
public string[] NameServers { get; }
|
||||||
@@ -16,13 +21,15 @@ public class Nameserver {
|
|||||||
string nameServers,
|
string nameServers,
|
||||||
string description,
|
string description,
|
||||||
string permissions,
|
string permissions,
|
||||||
DateTime? editDate
|
DateTime? editDate)
|
||||||
) {
|
{
|
||||||
this.Id = id;
|
Id = id;
|
||||||
this.Name = name;
|
Name = name;
|
||||||
this.NameServers = nameServers.Split(new char[] {';'});
|
NameServers = nameServers?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();
|
||||||
this.Description = description;
|
Description = description;
|
||||||
this.Permissions = permissions;
|
Permissions = permissions;
|
||||||
this.EditDate = editDate;
|
EditDate = editDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString() => Name;
|
||||||
}
|
}
|
||||||
@@ -1,57 +1,27 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a section in phpIPAM that organizes subnets.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Section {
|
public sealed record Section(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public string Name { get; }
|
string Name,
|
||||||
public string Description { get; }
|
string Description,
|
||||||
public int MasterSectionId { get; }
|
int MasterSectionId,
|
||||||
public string Permissions { get; }
|
string Permissions,
|
||||||
public bool StrictMode { get; }
|
bool StrictMode,
|
||||||
public string SubnetOrdering { get; }
|
string SubnetOrdering,
|
||||||
public int Order { get; }
|
int Order,
|
||||||
public DateTime? EditDate { get; }
|
DateTime? EditDate,
|
||||||
public bool ShowSubnet { get; }
|
bool ShowSubnet,
|
||||||
public bool ShowVlan { get; }
|
bool ShowVlan,
|
||||||
public bool ShowVRF { get; }
|
bool ShowVRF,
|
||||||
public bool ShowSupernetOnly { get; }
|
bool ShowSupernetOnly,
|
||||||
public int DNSId { get; }
|
int DNSId
|
||||||
|
)
|
||||||
public Section (
|
|
||||||
int id,
|
|
||||||
string name,
|
|
||||||
string description,
|
|
||||||
int masterSectionId,
|
|
||||||
string permissions,
|
|
||||||
bool strictMode,
|
|
||||||
string subnetOrdering,
|
|
||||||
int order,
|
|
||||||
DateTime? editDate,
|
|
||||||
bool showSubnet,
|
|
||||||
bool showVlan,
|
|
||||||
bool showVRF,
|
|
||||||
bool showSupernetOnly,
|
|
||||||
int dnsId
|
|
||||||
) {
|
|
||||||
this.Id = id;
|
|
||||||
this.Name = name;
|
|
||||||
this.Description = description;
|
|
||||||
this.MasterSectionId = masterSectionId;
|
|
||||||
this.Permissions = permissions;
|
|
||||||
this.StrictMode = strictMode;
|
|
||||||
this.SubnetOrdering = subnetOrdering;
|
|
||||||
this.Order = order;
|
|
||||||
this.EditDate = editDate;
|
|
||||||
this.ShowSubnet = showSubnet;
|
|
||||||
this.ShowVlan = showVlan;
|
|
||||||
this.ShowVRF = showVRF;
|
|
||||||
this.ShowSupernetOnly = showSupernetOnly;
|
|
||||||
this.DNSId = dnsId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return this.Name;
|
public override string ToString() => Name;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,27 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Management.Automation;
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an authenticated session with phpIPAM API.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Session {
|
public sealed record Session(
|
||||||
public AuthType AuthType { get; }
|
AuthType AuthType,
|
||||||
public string Token { get; set; }
|
string Token,
|
||||||
public string AppID { get; }
|
string AppID,
|
||||||
public string URL { get; }
|
string URL,
|
||||||
public DateTime? Expires { get; set; }
|
DateTime? Expires,
|
||||||
public object? Credentials { get; }
|
object? Credentials
|
||||||
public Session(
|
)
|
||||||
AuthType authType,
|
|
||||||
string token,
|
|
||||||
string appId,
|
|
||||||
string url,
|
|
||||||
DateTime? expires,
|
|
||||||
object? credentials
|
|
||||||
) {
|
|
||||||
AuthType = authType;
|
|
||||||
Token = token;
|
|
||||||
AppID = appId;
|
|
||||||
URL = url;
|
|
||||||
Expires = expires;
|
|
||||||
Credentials = credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return base.ToString();
|
/// <summary>
|
||||||
}
|
/// Gets or sets the current authentication token.
|
||||||
|
/// </summary>
|
||||||
|
public string Token { get; set; } = Token;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the token expiration time.
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? Expires { get; set; } = Expires;
|
||||||
}
|
}
|
||||||
@@ -1,114 +1,51 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a subnet/network in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Subnetwork {
|
public sealed record Subnetwork(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public string Subnet { get; }
|
string Subnet,
|
||||||
public int Mask { get; }
|
int Mask,
|
||||||
public int SectionId { get; }
|
int SectionId,
|
||||||
public string Description { get; }
|
string Description,
|
||||||
public string LinkedSubnet { get; }
|
string LinkedSubnet,
|
||||||
public string FirewallAddressObject { get; }
|
string FirewallAddressObject,
|
||||||
public int VrfId { get; }
|
int VrfId,
|
||||||
public int MasterSubnetId { get; }
|
int MasterSubnetId,
|
||||||
public bool AllowRequests { get; }
|
bool AllowRequests,
|
||||||
public int VlanId { get; }
|
int VlanId,
|
||||||
public bool ShowName { get; }
|
bool ShowName,
|
||||||
public int DeviceId { get; }
|
int DeviceId,
|
||||||
public string Permissions { get; }
|
string Permissions,
|
||||||
public bool PingSubnet { get; }
|
bool PingSubnet,
|
||||||
public bool DiscoverSubnet { get; }
|
bool DiscoverSubnet,
|
||||||
public bool ResolveDNS { get; }
|
bool ResolveDNS,
|
||||||
public bool DNSRecursive { get; }
|
bool DNSRecursive,
|
||||||
public bool DNSRecords { get; }
|
bool DNSRecords,
|
||||||
public int NameserverId { get; }
|
int NameserverId,
|
||||||
public bool ScanAgent { get; }
|
bool ScanAgent,
|
||||||
public bool IsFolder { get; }
|
bool IsFolder,
|
||||||
public bool IsFull { get; }
|
bool IsFull,
|
||||||
public bool IsPool { get; }
|
bool IsPool,
|
||||||
public int TagId { get; }
|
int TagId,
|
||||||
public int Threshold { get; }
|
int Threshold,
|
||||||
public int LocationId { get; }
|
int LocationId,
|
||||||
public DateTime? EditDate { get; }
|
DateTime? EditDate,
|
||||||
public DateTime? LastScan { get; }
|
DateTime? LastScan,
|
||||||
public DateTime? LastDiscovery { get; }
|
DateTime? LastDiscovery,
|
||||||
public Object Calculation { get; }
|
object Calculation,
|
||||||
public Object? ExtendedData { get; }
|
Dictionary<string, object>? ExtendedData = null
|
||||||
public Subnetwork(
|
)
|
||||||
int id,
|
|
||||||
string subnet,
|
|
||||||
int mask,
|
|
||||||
int sectionId,
|
|
||||||
string description,
|
|
||||||
string linkedSubnet,
|
|
||||||
string firewallAddressObject,
|
|
||||||
int vrfId,
|
|
||||||
int masterSubnetId,
|
|
||||||
bool allowRequests,
|
|
||||||
int vlanId,
|
|
||||||
bool showName,
|
|
||||||
int deviceId,
|
|
||||||
string permissions,
|
|
||||||
bool pingSubnet,
|
|
||||||
bool discoverSubnet,
|
|
||||||
bool resolveDNS,
|
|
||||||
bool dnsRecursive,
|
|
||||||
bool dnsRecords,
|
|
||||||
int nameserverId,
|
|
||||||
bool scanAgent,
|
|
||||||
bool isFolder,
|
|
||||||
bool isFull,
|
|
||||||
bool isPool,
|
|
||||||
int tagId,
|
|
||||||
int threshold,
|
|
||||||
int locationId,
|
|
||||||
DateTime? editDate,
|
|
||||||
DateTime? lastScan,
|
|
||||||
DateTime? lastDiscovery,
|
|
||||||
Object calculation,
|
|
||||||
Object? custom_fields
|
|
||||||
) {
|
|
||||||
this.Id = id;
|
|
||||||
this.Subnet = subnet;
|
|
||||||
this.Mask = mask;
|
|
||||||
this.SectionId = sectionId;
|
|
||||||
this.Description = description;
|
|
||||||
this.LinkedSubnet = linkedSubnet;
|
|
||||||
this.FirewallAddressObject = firewallAddressObject;
|
|
||||||
this.VrfId = vrfId;
|
|
||||||
this.MasterSubnetId = masterSubnetId;
|
|
||||||
this.AllowRequests = allowRequests;
|
|
||||||
this.VlanId = vlanId;
|
|
||||||
this.ShowName = showName;
|
|
||||||
this.DeviceId = deviceId;
|
|
||||||
this.Permissions = permissions;
|
|
||||||
this.PingSubnet = pingSubnet;
|
|
||||||
this.DiscoverSubnet = discoverSubnet;
|
|
||||||
this.ResolveDNS = resolveDNS;
|
|
||||||
this.DNSRecursive = dnsRecursive;
|
|
||||||
this.DNSRecords = dnsRecords;
|
|
||||||
this.NameserverId = nameserverId;
|
|
||||||
this.ScanAgent = scanAgent;
|
|
||||||
this.IsFolder = isFolder;
|
|
||||||
this.IsFull = isFull;
|
|
||||||
this.IsPool = isPool;
|
|
||||||
this.TagId = tagId;
|
|
||||||
this.Threshold = threshold;
|
|
||||||
this.LocationId = locationId;
|
|
||||||
this.EditDate = editDate;
|
|
||||||
this.LastScan = lastScan;
|
|
||||||
this.LastDiscovery = lastDiscovery;
|
|
||||||
this.Calculation = calculation;
|
|
||||||
this.ExtendedData = custom_fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetCIDR() {
|
|
||||||
return $"{this.Subnet}/{this.Mask}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return this.GetCIDR();
|
/// <summary>
|
||||||
}
|
/// Gets the subnet in CIDR notation (e.g., "192.168.1.0/24").
|
||||||
|
/// </summary>
|
||||||
|
public string CIDR => $"{Subnet}/{Mask}";
|
||||||
|
|
||||||
|
public override string ToString() => CIDR;
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,21 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an address tag in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Tag {
|
public sealed record Tag(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public string Type { get; }
|
string Type,
|
||||||
public bool ShowTag { get; }
|
bool ShowTag,
|
||||||
public string BGColor { get; }
|
string BackgroundColor,
|
||||||
public string FGColor { get; }
|
string ForegroundColor,
|
||||||
public bool Compress { get; }
|
string Compress,
|
||||||
public bool Locked { get; }
|
string Locked,
|
||||||
public bool UpdateTag { get; }
|
bool UpdateTag
|
||||||
|
)
|
||||||
public Tag(
|
{
|
||||||
int id,
|
public override string ToString() => Type;
|
||||||
string type,
|
|
||||||
bool showTag,
|
|
||||||
string BGColor,
|
|
||||||
string FGColor,
|
|
||||||
string compress,
|
|
||||||
string locked,
|
|
||||||
bool updateTag
|
|
||||||
) {
|
|
||||||
this.Id = id;
|
|
||||||
this.Type = type;
|
|
||||||
this.ShowTag = showTag;
|
|
||||||
this.BGColor = BGColor;
|
|
||||||
this.FGColor = FGColor;
|
|
||||||
this.Compress = this.StringToBool(compress);
|
|
||||||
this.Locked = this.StringToBool(locked);
|
|
||||||
this.UpdateTag = updateTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return this.Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool StringToBool(string str) {
|
|
||||||
if (str == "Yes") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,41 +1,27 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Dynamic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a VLAN in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Vlan : DynamicObject {
|
public sealed record Vlan(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public int VlanId { get; }
|
int DomainId,
|
||||||
public int DomainId { get; }
|
string Name,
|
||||||
public string Name { get; }
|
int Number,
|
||||||
public int Number { get; }
|
string Description,
|
||||||
public string Description { get; }
|
DateTime? EditDate,
|
||||||
public DateTime? EditDate { get; }
|
int CustomerId,
|
||||||
public int CustomerId { get; }
|
Dictionary<string, object>? ExtendedData = null
|
||||||
public Object? ExtendedData { get; }
|
)
|
||||||
public Vlan (
|
|
||||||
int vlanId,
|
|
||||||
int domainId,
|
|
||||||
string name,
|
|
||||||
int number,
|
|
||||||
string description,
|
|
||||||
DateTime? editDate,
|
|
||||||
int customer_id,
|
|
||||||
Object? custom_fields
|
|
||||||
) {
|
|
||||||
this.Id = vlanId;
|
|
||||||
this.VlanId = vlanId;
|
|
||||||
this.DomainId = domainId;
|
|
||||||
this.Name = name;
|
|
||||||
this.Number = number;
|
|
||||||
this.Description = description;
|
|
||||||
this.EditDate = editDate;
|
|
||||||
this.CustomerId = customer_id;
|
|
||||||
this.ExtendedData = custom_fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return $"{this.Number}";
|
/// <summary>
|
||||||
}
|
/// Alias for Id to maintain API compatibility.
|
||||||
|
/// </summary>
|
||||||
|
public int VlanId => Id;
|
||||||
|
|
||||||
|
public override string ToString() => Number.ToString();
|
||||||
}
|
}
|
||||||
@@ -1,35 +1,21 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a VRF (Virtual Routing and Forwarding) instance in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Vrf {
|
public sealed record Vrf(
|
||||||
public int Id { get; }
|
int Id,
|
||||||
public string Name { get; }
|
string Name,
|
||||||
public string RouteDistinguisher { get; }
|
string RouteDistinguisher,
|
||||||
public string Description { get; }
|
string Description,
|
||||||
public string Sections { get; }
|
string Sections,
|
||||||
public DateTime? EditDate { get; }
|
DateTime? EditDate,
|
||||||
public Object? ExtendedData { get; }
|
Dictionary<string, object>? ExtendedData = null
|
||||||
|
)
|
||||||
public Vrf(
|
|
||||||
int id,
|
|
||||||
string name,
|
|
||||||
string rd,
|
|
||||||
string description,
|
|
||||||
string sections,
|
|
||||||
DateTime? editDate,
|
|
||||||
Object? custom_fields
|
|
||||||
) {
|
|
||||||
this.Id = id;
|
|
||||||
this.Name = name;
|
|
||||||
this.RouteDistinguisher = rd;
|
|
||||||
this.Description = description;
|
|
||||||
this.Sections = sections;
|
|
||||||
this.EditDate = editDate;
|
|
||||||
this.ExtendedData = custom_fields;
|
|
||||||
}
|
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return this.Name;
|
public override string ToString() => Name;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,20 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the authentication method for phpIPAM API.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public enum AuthType {
|
public enum AuthType
|
||||||
credentials,
|
{
|
||||||
token
|
/// <summary>
|
||||||
|
/// Authentication using username and password credentials.
|
||||||
|
/// </summary>
|
||||||
|
Credentials,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authentication using a static API token.
|
||||||
|
/// </summary>
|
||||||
|
Token
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the main API controllers in phpIPAM.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public enum controllers {
|
public enum ApiController
|
||||||
user,
|
{
|
||||||
vlan,
|
User,
|
||||||
subnets,
|
Vlan,
|
||||||
addresses,
|
Subnets,
|
||||||
sections,
|
Addresses,
|
||||||
vrf,
|
Sections,
|
||||||
l2domains,
|
Vrf,
|
||||||
tools
|
L2Domains,
|
||||||
|
Tools
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,21 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents sub-controllers/endpoints within main API controllers.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public enum subcontrollers {
|
public enum ApiSubController
|
||||||
nameservers,
|
{
|
||||||
tags,
|
Nameservers,
|
||||||
devices,
|
Tags,
|
||||||
device_types,
|
Devices,
|
||||||
vlans,
|
DeviceTypes,
|
||||||
vrfs,
|
Vlans,
|
||||||
scanagents,
|
Vrfs,
|
||||||
locations,
|
ScanAgents,
|
||||||
nat,
|
Locations,
|
||||||
racks
|
Nat,
|
||||||
|
Racks
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
namespace PS.IPAM;
|
namespace PS.IPAM;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the model types returned by the phpIPAM API.
|
||||||
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public enum types {
|
public enum ModelType
|
||||||
|
{
|
||||||
Address,
|
Address,
|
||||||
Domain,
|
Domain,
|
||||||
Section,
|
Section,
|
||||||
|
|||||||
Reference in New Issue
Block a user