mirror of
https://github.com/freedbygrace/PSOPNSenseAPI.git
synced 2026-07-27 12:19:12 +00:00
Add port forwarding support, improve XML documentation, and add unit tests
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Services;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class ApiClientTests
|
||||
{
|
||||
private Mock<ILogger> _loggerMock;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Constructor_ValidParameters_CreatesClient()
|
||||
{
|
||||
// Arrange
|
||||
string baseUrl = "https://firewall.example.com";
|
||||
string apiKey = "key";
|
||||
string apiSecret = "secret";
|
||||
bool skipCertificateCheck = true;
|
||||
|
||||
// Act
|
||||
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(client);
|
||||
Assert.AreEqual(baseUrl, client.BaseUrl);
|
||||
Assert.IsTrue(client.IsConnected);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void Constructor_NullBaseUrl_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
string baseUrl = null;
|
||||
string apiKey = "key";
|
||||
string apiSecret = "secret";
|
||||
bool skipCertificateCheck = true;
|
||||
|
||||
// Act
|
||||
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
|
||||
|
||||
// Assert - Exception expected
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void Constructor_NullApiKey_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
string baseUrl = "https://firewall.example.com";
|
||||
string apiKey = null;
|
||||
string apiSecret = "secret";
|
||||
bool skipCertificateCheck = true;
|
||||
|
||||
// Act
|
||||
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
|
||||
|
||||
// Assert - Exception expected
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void Constructor_NullApiSecret_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
string baseUrl = "https://firewall.example.com";
|
||||
string apiKey = "key";
|
||||
string apiSecret = null;
|
||||
bool skipCertificateCheck = true;
|
||||
|
||||
// Act
|
||||
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
|
||||
|
||||
// Assert - Exception expected
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void Constructor_NullLogger_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
string baseUrl = "https://firewall.example.com";
|
||||
string apiKey = "key";
|
||||
string apiSecret = "secret";
|
||||
bool skipCertificateCheck = true;
|
||||
|
||||
// Act
|
||||
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, null);
|
||||
|
||||
// Assert - Exception expected
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Dispose_SetsIsConnectedToFalse()
|
||||
{
|
||||
// Arrange
|
||||
string baseUrl = "https://firewall.example.com";
|
||||
string apiKey = "key";
|
||||
string apiSecret = "secret";
|
||||
bool skipCertificateCheck = true;
|
||||
var client = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, _loggerMock.Object);
|
||||
|
||||
// Act
|
||||
client.Dispose();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(client.IsConnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using PSOPNSenseAPI.Cmdlets;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Tests.Cmdlets
|
||||
{
|
||||
[TestClass]
|
||||
public class GetOPNSenseAliasCmdletTests
|
||||
{
|
||||
private Mock<OPNSenseApiClient> _apiClientMock;
|
||||
private Mock<ILogger> _loggerMock;
|
||||
private GetOPNSenseAliasCmdlet _cmdlet;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
|
||||
_cmdlet = new GetOPNSenseAliasCmdlet();
|
||||
|
||||
// Use reflection to set private fields
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_GetAllAliases_WritesAliasesToPipeline()
|
||||
{
|
||||
// Arrange
|
||||
var aliases = new List<Alias>
|
||||
{
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid1",
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Enabled = "1"
|
||||
},
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid2",
|
||||
Name = "WebPorts",
|
||||
Type = "port",
|
||||
Content = "80,443",
|
||||
Description = "Web Ports",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var response = new AliasListResponse
|
||||
{
|
||||
Total = aliases.Count,
|
||||
RowCount = aliases.Count,
|
||||
Current = 1,
|
||||
Rows = aliases
|
||||
};
|
||||
|
||||
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
|
||||
aliasServiceMock.Setup(x => x.GetAliasesAsync()).ReturnsAsync(response);
|
||||
|
||||
// Mock the AliasService creation
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasListResponse>();
|
||||
taskCompletionSource.SetResult(response);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, results.Count);
|
||||
Assert.IsInstanceOfType(results[0], typeof(Alias));
|
||||
Assert.IsInstanceOfType(results[1], typeof(Alias));
|
||||
|
||||
var alias1 = results[0] as Alias;
|
||||
var alias2 = results[1] as Alias;
|
||||
|
||||
Assert.AreEqual("WebServers", alias1.Name);
|
||||
Assert.AreEqual("WebPorts", alias2.Name);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_GetAliasByUuid_WritesAliasDetailToPipeline()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "uuid1";
|
||||
_cmdlet.Uuid = uuid;
|
||||
|
||||
// Use reflection to set the parameter set name
|
||||
typeof(PSCmdlet).GetProperty("ParameterSetName").SetValue(_cmdlet, "ByUuid");
|
||||
|
||||
var aliasDetail = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
};
|
||||
|
||||
var response = new AliasResponse
|
||||
{
|
||||
Alias = aliasDetail
|
||||
};
|
||||
|
||||
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
|
||||
aliasServiceMock.Setup(x => x.GetAliasAsync(uuid)).ReturnsAsync(response);
|
||||
|
||||
// Mock the AliasService creation
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
taskCompletionSource.SetResult(response);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.IsInstanceOfType(results[0], typeof(AliasDetail));
|
||||
|
||||
var alias = results[0] as AliasDetail;
|
||||
|
||||
Assert.AreEqual("WebServers", alias.Name);
|
||||
Assert.AreEqual("host", alias.Type);
|
||||
Assert.AreEqual("192.168.1.10,192.168.1.11", alias.Content);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_GetAliasByName_WritesFilteredAliasesToPipeline()
|
||||
{
|
||||
// Arrange
|
||||
string name = "WebServers";
|
||||
_cmdlet.Name = name;
|
||||
|
||||
// Use reflection to set the parameter set name
|
||||
typeof(PSCmdlet).GetProperty("ParameterSetName").SetValue(_cmdlet, "ByName");
|
||||
|
||||
var aliases = new List<Alias>
|
||||
{
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid1",
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Enabled = "1"
|
||||
},
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid2",
|
||||
Name = "WebPorts",
|
||||
Type = "port",
|
||||
Content = "80,443",
|
||||
Description = "Web Ports",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var response = new AliasListResponse
|
||||
{
|
||||
Total = aliases.Count,
|
||||
RowCount = aliases.Count,
|
||||
Current = 1,
|
||||
Rows = aliases
|
||||
};
|
||||
|
||||
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
|
||||
aliasServiceMock.Setup(x => x.GetAliasesAsync()).ReturnsAsync(response);
|
||||
|
||||
// Mock the AliasService creation
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasListResponse>();
|
||||
taskCompletionSource.SetResult(response);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.IsInstanceOfType(results[0], typeof(Alias));
|
||||
|
||||
var alias = results[0] as Alias;
|
||||
|
||||
Assert.AreEqual("WebServers", alias.Name);
|
||||
Assert.AreEqual("host", alias.Type);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_GetAliasByType_WritesFilteredAliasesToPipeline()
|
||||
{
|
||||
// Arrange
|
||||
string type = "host";
|
||||
_cmdlet.Type = type;
|
||||
|
||||
var aliases = new List<Alias>
|
||||
{
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid1",
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Enabled = "1"
|
||||
},
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid2",
|
||||
Name = "WebPorts",
|
||||
Type = "port",
|
||||
Content = "80,443",
|
||||
Description = "Web Ports",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var response = new AliasListResponse
|
||||
{
|
||||
Total = aliases.Count,
|
||||
RowCount = aliases.Count,
|
||||
Current = 1,
|
||||
Rows = aliases
|
||||
};
|
||||
|
||||
var aliasServiceMock = new Mock<AliasService>(_apiClientMock.Object, _loggerMock.Object);
|
||||
aliasServiceMock.Setup(x => x.GetAliasesAsync()).ReturnsAsync(response);
|
||||
|
||||
// Mock the AliasService creation
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasListResponse>();
|
||||
taskCompletionSource.SetResult(response);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.IsInstanceOfType(results[0], typeof(Alias));
|
||||
|
||||
var alias = results[0] as Alias;
|
||||
|
||||
Assert.AreEqual("WebServers", alias.Name);
|
||||
Assert.AreEqual("host", alias.Type);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper class for testing cmdlets
|
||||
public class MockCommandRuntime : ICommandRuntime
|
||||
{
|
||||
private readonly Action<object> _outputHandler;
|
||||
private readonly Action<string> _warningHandler;
|
||||
private readonly Action<string> _verboseHandler;
|
||||
private readonly bool _shouldProcessResult;
|
||||
|
||||
public MockCommandRuntime(Action<object> outputHandler, Action<string> warningHandler = null, Action<string> verboseHandler = null, bool shouldProcessResult = true)
|
||||
{
|
||||
_outputHandler = outputHandler;
|
||||
_warningHandler = warningHandler ?? (_ => { });
|
||||
_verboseHandler = verboseHandler ?? (_ => { });
|
||||
_shouldProcessResult = shouldProcessResult;
|
||||
}
|
||||
|
||||
public PSHost Host => throw new NotImplementedException();
|
||||
|
||||
public PSTransactionContext CurrentPSTransaction => throw new NotImplementedException();
|
||||
|
||||
public virtual bool ShouldProcess(string target) => _shouldProcessResult;
|
||||
|
||||
public virtual bool ShouldProcess(string target, string action) => _shouldProcessResult;
|
||||
|
||||
public virtual bool ShouldProcess(string verboseDescription, string verboseWarning, string caption) => _shouldProcessResult;
|
||||
|
||||
public virtual bool ShouldProcess(string verboseDescription, string verboseWarning, string caption, out ShouldProcessReason shouldProcessReason)
|
||||
{
|
||||
shouldProcessReason = ShouldProcessReason.None;
|
||||
return _shouldProcessResult;
|
||||
}
|
||||
|
||||
public bool ShouldContinue(string query, string caption) => true;
|
||||
|
||||
public bool ShouldContinue(string query, string caption, ref bool yesToAll, ref bool noToAll) => true;
|
||||
|
||||
public void WriteCommandDetail(string text) { }
|
||||
|
||||
public void WriteDebug(string text) { }
|
||||
|
||||
public void WriteError(ErrorRecord errorRecord) { throw errorRecord.Exception; }
|
||||
|
||||
public void WriteObject(object sendToPipeline) => _outputHandler(sendToPipeline);
|
||||
|
||||
public void WriteObject(object sendToPipeline, bool enumerateCollection)
|
||||
{
|
||||
if (enumerateCollection && sendToPipeline is IEnumerable<object> enumerable)
|
||||
{
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
_outputHandler(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_outputHandler(sendToPipeline);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteProgress(ProgressRecord progressRecord) { }
|
||||
|
||||
public void WriteProgress(long sourceId, ProgressRecord progressRecord) { }
|
||||
|
||||
public void WriteVerbose(string text) => _verboseHandler(text);
|
||||
|
||||
public void WriteWarning(string text) => _warningHandler(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using PSOPNSenseAPI.Cmdlets;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Tests.Cmdlets
|
||||
{
|
||||
[TestClass]
|
||||
public class NewOPNSenseAliasCmdletTests
|
||||
{
|
||||
private Mock<OPNSenseApiClient> _apiClientMock;
|
||||
private Mock<ILogger> _loggerMock;
|
||||
private NewOPNSenseAliasCmdlet _cmdlet;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
|
||||
_cmdlet = new NewOPNSenseAliasCmdlet();
|
||||
|
||||
// Use reflection to set private fields
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_CreateHostAlias_ReturnsUuid()
|
||||
{
|
||||
// Arrange
|
||||
_cmdlet.Name = "WebServers";
|
||||
_cmdlet.Type = "host";
|
||||
_cmdlet.Content = "192.168.1.10,192.168.1.11";
|
||||
_cmdlet.Description = "Web Servers";
|
||||
|
||||
var expectedResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
// Mock the API client response
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
|
||||
taskCompletionSource.SetResult(expectedResponse);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual("new-uuid", results[0]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_CreatePortAlias_WithProtocol_ReturnsUuid()
|
||||
{
|
||||
// Arrange
|
||||
_cmdlet.Name = "WebPorts";
|
||||
_cmdlet.Type = "port";
|
||||
_cmdlet.Content = "80,443";
|
||||
_cmdlet.Description = "Web Ports";
|
||||
_cmdlet.Protocol = "TCP";
|
||||
|
||||
var expectedResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
// Mock the API client response
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
|
||||
taskCompletionSource.SetResult(expectedResponse);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual("new-uuid", results[0]);
|
||||
|
||||
// Verify the correct protocol was set
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Protocol").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "TCP")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_CreateUrlAlias_WithUpdateFrequency_ReturnsUuid()
|
||||
{
|
||||
// Arrange
|
||||
_cmdlet.Name = "BlockList";
|
||||
_cmdlet.Type = "url";
|
||||
_cmdlet.Content = "https://example.com/blocklist.txt";
|
||||
_cmdlet.Description = "Block List";
|
||||
_cmdlet.UpdateFrequency = 1;
|
||||
|
||||
var expectedResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
// Mock the API client response
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
|
||||
taskCompletionSource.SetResult(expectedResponse);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual("new-uuid", results[0]);
|
||||
|
||||
// Verify the correct update frequency was set
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("UpdateFrequency").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_CreateDisabledAlias_ReturnsUuid()
|
||||
{
|
||||
// Arrange
|
||||
_cmdlet.Name = "WebServers";
|
||||
_cmdlet.Type = "host";
|
||||
_cmdlet.Content = "192.168.1.10,192.168.1.11";
|
||||
_cmdlet.Description = "Web Servers";
|
||||
_cmdlet.Disabled = true;
|
||||
|
||||
var expectedResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
// Mock the API client response
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
|
||||
taskCompletionSource.SetResult(expectedResponse);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual("new-uuid", results[0]);
|
||||
|
||||
// Verify the alias was created as disabled
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "0")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_CreateAliasWithCounters_ReturnsUuid()
|
||||
{
|
||||
// Arrange
|
||||
_cmdlet.Name = "WebServers";
|
||||
_cmdlet.Type = "host";
|
||||
_cmdlet.Content = "192.168.1.10,192.168.1.11";
|
||||
_cmdlet.Description = "Web Servers";
|
||||
_cmdlet.EnableCounters = true;
|
||||
|
||||
var expectedResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
// Mock the API client response
|
||||
var taskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
|
||||
taskCompletionSource.SetResult(expectedResponse);
|
||||
var task = taskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.Returns(task);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual("new-uuid", results[0]);
|
||||
|
||||
// Verify the alias was created with counters enabled
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Counters").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_CreateAliasAndApply_ReconfiguresAliases()
|
||||
{
|
||||
// Arrange
|
||||
_cmdlet.Name = "WebServers";
|
||||
_cmdlet.Type = "host";
|
||||
_cmdlet.Content = "192.168.1.10,192.168.1.11";
|
||||
_cmdlet.Description = "Web Servers";
|
||||
_cmdlet.Apply = true;
|
||||
|
||||
var createResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
var reconfigureResponse = new AliasReconfigureResponse
|
||||
{
|
||||
Status = "ok"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var createTaskCompletionSource = new TaskCompletionSource<AliasCreateResponse>();
|
||||
createTaskCompletionSource.SetResult(createResponse);
|
||||
var createTask = createTaskCompletionSource.Task;
|
||||
|
||||
var reconfigureTaskCompletionSource = new TaskCompletionSource<AliasReconfigureResponse>();
|
||||
reconfigureTaskCompletionSource.SetResult(reconfigureResponse);
|
||||
var reconfigureTask = reconfigureTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.Returns(createTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
|
||||
.Returns(reconfigureTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual("new-uuid", results[0]);
|
||||
|
||||
// Verify the reconfigure method was called
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using PSOPNSenseAPI.Cmdlets;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Tests.Cmdlets
|
||||
{
|
||||
[TestClass]
|
||||
public class RemoveOPNSenseAliasCmdletTests
|
||||
{
|
||||
private Mock<OPNSenseApiClient> _apiClientMock;
|
||||
private Mock<ILogger> _loggerMock;
|
||||
private RemoveOPNSenseAliasCmdlet _cmdlet;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
|
||||
_cmdlet = new RemoveOPNSenseAliasCmdlet();
|
||||
|
||||
// Use reflection to set private fields
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_RemoveAliasWithForce_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Force = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var deleteResponse = new AliasDeleteResponse
|
||||
{
|
||||
Result = "deleted"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var deleteTaskCompletionSource = new TaskCompletionSource<AliasDeleteResponse>();
|
||||
deleteTaskCompletionSource.SetResult(deleteResponse);
|
||||
var deleteTask = deleteTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
|
||||
.Returns(deleteTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the delete method was called
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_RemoveAliasWithShouldProcess_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var deleteResponse = new AliasDeleteResponse
|
||||
{
|
||||
Result = "deleted"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var deleteTaskCompletionSource = new TaskCompletionSource<AliasDeleteResponse>();
|
||||
deleteTaskCompletionSource.SetResult(deleteResponse);
|
||||
var deleteTask = deleteTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
|
||||
.Returns(deleteTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output with ShouldProcess always returning true
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the delete method was called
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_RemoveAliasAndApply_ReconfiguresAliases()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Force = true;
|
||||
_cmdlet.Apply = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var deleteResponse = new AliasDeleteResponse
|
||||
{
|
||||
Result = "deleted"
|
||||
};
|
||||
|
||||
var reconfigureResponse = new AliasReconfigureResponse
|
||||
{
|
||||
Status = "ok"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var deleteTaskCompletionSource = new TaskCompletionSource<AliasDeleteResponse>();
|
||||
deleteTaskCompletionSource.SetResult(deleteResponse);
|
||||
var deleteTask = deleteTaskCompletionSource.Task;
|
||||
|
||||
var reconfigureTaskCompletionSource = new TaskCompletionSource<AliasReconfigureResponse>();
|
||||
reconfigureTaskCompletionSource.SetResult(reconfigureResponse);
|
||||
var reconfigureTask = reconfigureTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
|
||||
.Returns(deleteTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
|
||||
.Returns(reconfigureTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the delete and reconfigure methods were called
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"), Times.Once);
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"), Times.Once);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using PSOPNSenseAPI.Cmdlets;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Tests.Cmdlets
|
||||
{
|
||||
[TestClass]
|
||||
public class SetOPNSenseAliasCmdletTests
|
||||
{
|
||||
private Mock<OPNSenseApiClient> _apiClientMock;
|
||||
private Mock<ILogger> _loggerMock;
|
||||
private SetOPNSenseAliasCmdlet _cmdlet;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
|
||||
_cmdlet = new SetOPNSenseAliasCmdlet();
|
||||
|
||||
// Use reflection to set private fields
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("ApiClient").SetValue(_cmdlet, _apiClientMock.Object);
|
||||
typeof(OPNSenseBaseCmdlet).GetProperty("Logger").SetValue(_cmdlet, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_UpdateAliasContent_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Content = "192.168.1.10,192.168.1.11,192.168.1.12";
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the update method was called with the correct content
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Content").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "192.168.1.10,192.168.1.11,192.168.1.12")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_UpdateAliasDescription_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Description = "Updated Web Servers";
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the update method was called with the correct description
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Description").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "Updated Web Servers")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_DisableAlias_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Disabled = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the update method was called with the alias disabled
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "0")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_EnableAlias_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Enabled = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "0"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the update method was called with the alias enabled
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_EnableCounters_Success()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.EnableCounters = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the update method was called with counters enabled
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Counters").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
|
||||
Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_UpdateAndApply_ReconfiguresAliases()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Content = "192.168.1.10,192.168.1.11,192.168.1.12";
|
||||
_cmdlet.Apply = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
var reconfigureResponse = new AliasReconfigureResponse
|
||||
{
|
||||
Status = "ok"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
var reconfigureTaskCompletionSource = new TaskCompletionSource<AliasReconfigureResponse>();
|
||||
reconfigureTaskCompletionSource.SetResult(reconfigureResponse);
|
||||
var reconfigureTask = reconfigureTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
|
||||
.Returns(reconfigureTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output));
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the reconfigure method was called
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessRecord_BothEnabledAndDisabled_UsesEnabled()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "test-uuid";
|
||||
_cmdlet.Uuid = uuid;
|
||||
_cmdlet.Enabled = true;
|
||||
_cmdlet.Disabled = true;
|
||||
|
||||
var getResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "0"
|
||||
}
|
||||
};
|
||||
|
||||
var updateResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
// Mock the API client responses
|
||||
var getTaskCompletionSource = new TaskCompletionSource<AliasResponse>();
|
||||
getTaskCompletionSource.SetResult(getResponse);
|
||||
var getTask = getTaskCompletionSource.Task;
|
||||
|
||||
var updateTaskCompletionSource = new TaskCompletionSource<AliasUpdateResponse>();
|
||||
updateTaskCompletionSource.SetResult(updateResponse);
|
||||
var updateTask = updateTaskCompletionSource.Task;
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.Returns(getTask);
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.Returns(updateTask);
|
||||
|
||||
// Create a PowerShell pipeline to capture output
|
||||
var results = new List<object>();
|
||||
_cmdlet.CommandRuntime = new MockCommandRuntime(output => results.Add(output), warning => { });
|
||||
|
||||
// Act
|
||||
_cmdlet.ProcessRecord();
|
||||
|
||||
// Assert
|
||||
// Verify the update method was called with the alias enabled
|
||||
_apiClientMock.Verify(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}",
|
||||
It.Is<object>(o =>
|
||||
o.GetType().GetProperty("alias").GetValue(o, null).GetType().GetProperty("Enabled").GetValue(
|
||||
o.GetType().GetProperty("alias").GetValue(o, null), null).ToString() == "1")),
|
||||
Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
|
||||
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PSOPNSenseAPI\PSOPNSenseAPI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,211 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PSOPNSenseAPI.Tests.Services
|
||||
{
|
||||
[TestClass]
|
||||
public class AliasServiceTests
|
||||
{
|
||||
private Mock<OPNSenseApiClient> _apiClientMock;
|
||||
private Mock<ILogger> _loggerMock;
|
||||
private AliasService _aliasService;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_apiClientMock = new Mock<OPNSenseApiClient>("https://example.com", "key", "secret", false, Mock.Of<ILogger>());
|
||||
_loggerMock = new Mock<ILogger>();
|
||||
_aliasService = new AliasService(_apiClientMock.Object, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetAliasesAsync_ReturnsAliases()
|
||||
{
|
||||
// Arrange
|
||||
var expectedResponse = new AliasListResponse
|
||||
{
|
||||
Total = 2,
|
||||
RowCount = 2,
|
||||
Current = 1,
|
||||
Rows = new List<Alias>
|
||||
{
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid1",
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Enabled = "1"
|
||||
},
|
||||
new Alias
|
||||
{
|
||||
Uuid = "uuid2",
|
||||
Name = "WebPorts",
|
||||
Type = "port",
|
||||
Content = "80,443",
|
||||
Description = "Web Ports",
|
||||
Enabled = "1"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasListResponse>("firewall/alias/searchItem"))
|
||||
.ReturnsAsync(expectedResponse);
|
||||
|
||||
// Act
|
||||
var result = await _aliasService.GetAliasesAsync();
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(2, result.Total);
|
||||
Assert.AreEqual(2, result.Rows.Count);
|
||||
Assert.AreEqual("WebServers", result.Rows[0].Name);
|
||||
Assert.AreEqual("WebPorts", result.Rows[1].Name);
|
||||
_loggerMock.Verify(x => x.Information("Getting aliases"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetAliasAsync_ReturnsAlias()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "uuid1";
|
||||
var expectedResponse = new AliasResponse
|
||||
{
|
||||
Alias = new AliasDetail
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Protocol = "",
|
||||
UpdateFrequency = "",
|
||||
Counters = "0",
|
||||
Enabled = "1"
|
||||
}
|
||||
};
|
||||
|
||||
_apiClientMock.Setup(x => x.GetAsync<AliasResponse>($"firewall/alias/getItem/{uuid}"))
|
||||
.ReturnsAsync(expectedResponse);
|
||||
|
||||
// Act
|
||||
var result = await _aliasService.GetAliasAsync(uuid);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("WebServers", result.Alias.Name);
|
||||
Assert.AreEqual("host", result.Alias.Type);
|
||||
_loggerMock.Verify(x => x.Information($"Getting alias with UUID {uuid}"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CreateAliasAsync_ReturnsUuid()
|
||||
{
|
||||
// Arrange
|
||||
var alias = new AliasConfig
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11",
|
||||
Description = "Web Servers",
|
||||
Enabled = "1"
|
||||
};
|
||||
|
||||
var expectedResponse = new AliasCreateResponse
|
||||
{
|
||||
Uuid = "new-uuid"
|
||||
};
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasCreateResponse>("firewall/alias/addItem", It.IsAny<object>()))
|
||||
.ReturnsAsync(expectedResponse);
|
||||
|
||||
// Act
|
||||
var result = await _aliasService.CreateAliasAsync(alias);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("new-uuid", result.Uuid);
|
||||
_loggerMock.Verify(x => x.Information("Creating alias"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task UpdateAliasAsync_ReturnsSuccess()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "uuid1";
|
||||
var alias = new AliasConfig
|
||||
{
|
||||
Name = "WebServers",
|
||||
Type = "host",
|
||||
Content = "192.168.1.10,192.168.1.11,192.168.1.12",
|
||||
Description = "Updated Web Servers",
|
||||
Enabled = "1"
|
||||
};
|
||||
|
||||
var expectedResponse = new AliasUpdateResponse
|
||||
{
|
||||
Result = "saved"
|
||||
};
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasUpdateResponse>($"firewall/alias/setItem/{uuid}", It.IsAny<object>()))
|
||||
.ReturnsAsync(expectedResponse);
|
||||
|
||||
// Act
|
||||
var result = await _aliasService.UpdateAliasAsync(uuid, alias);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("saved", result.Result);
|
||||
_loggerMock.Verify(x => x.Information($"Updating alias with UUID {uuid}"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task DeleteAliasAsync_ReturnsSuccess()
|
||||
{
|
||||
// Arrange
|
||||
string uuid = "uuid1";
|
||||
var expectedResponse = new AliasDeleteResponse
|
||||
{
|
||||
Result = "deleted"
|
||||
};
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasDeleteResponse>($"firewall/alias/delItem/{uuid}"))
|
||||
.ReturnsAsync(expectedResponse);
|
||||
|
||||
// Act
|
||||
var result = await _aliasService.DeleteAliasAsync(uuid);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("deleted", result.Result);
|
||||
_loggerMock.Verify(x => x.Information($"Deleting alias with UUID {uuid}"), Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ReconfigureAliasesAsync_ReturnsSuccess()
|
||||
{
|
||||
// Arrange
|
||||
var expectedResponse = new AliasReconfigureResponse
|
||||
{
|
||||
Status = "ok"
|
||||
};
|
||||
|
||||
_apiClientMock.Setup(x => x.PostAsync<AliasReconfigureResponse>("firewall/alias/reconfigure"))
|
||||
.ReturnsAsync(expectedResponse);
|
||||
|
||||
// Act
|
||||
var result = await _aliasService.ReconfigureAliasesAsync();
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("ok", result.Status);
|
||||
_loggerMock.Verify(x => x.Information("Reconfiguring aliases"), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Applies firewall changes on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Apply-OPNSenseFirewallChanges cmdlet applies pending firewall changes on an OPNSense firewall.</para>
|
||||
/// <para type="description">This cmdlet creates a savepoint before applying changes, which allows for automatic rollback if the changes cause connectivity issues.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Apply firewall changes</para>
|
||||
/// <code>Apply-OPNSenseFirewallChanges</code>
|
||||
/// <para>This example applies pending firewall changes with automatic rollback if connectivity is lost.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Apply firewall changes without automatic rollback</para>
|
||||
/// <code>Apply-OPNSenseFirewallChanges -NoRollback</code>
|
||||
/// <para>This example applies pending firewall changes without creating a savepoint for automatic rollback.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Update, "OPNSenseFirewallChanges")]
|
||||
[OutputType(typeof(void))]
|
||||
public class ApplyOPNSenseFirewallChangesCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Applies changes without creating a savepoint for automatic rollback.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter NoRollback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Cancels the automatic rollback after applying changes.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter CancelRollback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timeout in seconds to wait before cancelling the rollback.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 300)]
|
||||
public int Timeout { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
if (NoRollback.IsPresent)
|
||||
{
|
||||
WriteVerbose("Applying firewall changes without rollback protection");
|
||||
var applyTask = Task.Run(async () => await firewallService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
WriteVerbose($"Firewall changes applied: {applyResult.Status}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVerbose("Creating savepoint for rollback protection");
|
||||
var savepointTask = Task.Run(async () => await firewallService.CreateSavepointAsync());
|
||||
var savepointResult = savepointTask.GetAwaiter().GetResult();
|
||||
var revision = savepointResult.Revision;
|
||||
|
||||
WriteVerbose($"Created savepoint with revision {revision}");
|
||||
WriteVerbose("Applying firewall changes with rollback protection");
|
||||
|
||||
var applyTask = Task.Run(async () => await firewallService.ApplyChangesAsync(revision));
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firewall changes applied: {applyResult.Status}");
|
||||
|
||||
if (CancelRollback.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting {Timeout} seconds before cancelling rollback");
|
||||
System.Threading.Thread.Sleep(Timeout * 1000);
|
||||
|
||||
WriteVerbose("Cancelling automatic rollback");
|
||||
var cancelTask = Task.Run(async () => await firewallService.CancelRollbackAsync(revision));
|
||||
var cancelResult = cancelTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Rollback cancelled: {cancelResult.Status}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteVerbose($"Automatic rollback will occur in 60 seconds if connectivity is lost");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a backup of the OPNSense firewall configuration.</para>
|
||||
/// <para type="description">The Backup-OPNSenseConfig cmdlet creates a backup of the OPNSense firewall configuration.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a backup</para>
|
||||
/// <code>Backup-OPNSenseConfig</code>
|
||||
/// <para>This example creates a backup of the OPNSense firewall configuration with an automatically generated filename.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Create a backup with a specific filename</para>
|
||||
/// <code>Backup-OPNSenseConfig -Filename "pre-upgrade-backup"</code>
|
||||
/// <para>This example creates a backup of the OPNSense firewall configuration with a specific filename.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Backup, "OPNSenseConfig")]
|
||||
[OutputType(typeof(string))]
|
||||
public class BackupOPNSenseConfigCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The filename for the backup.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0)]
|
||||
public string Filename { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configService = new ConfigService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await configService.CreateConfigBackupAsync(Filename));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created configuration backup: {result.Filename}");
|
||||
WriteObject(result.Filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Models;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Connects to an OPNSense firewall.</para>
|
||||
/// <para type="description">The Connect-OPNSense cmdlet establishes a connection to an OPNSense firewall using the API.</para>
|
||||
/// <para type="description">This cmdlet must be called before using any other cmdlets in the module.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Connect to an OPNSense firewall</para>
|
||||
/// <code>Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret"</code>
|
||||
/// <para>This example connects to an OPNSense firewall at the specified URL using the provided API credentials.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Connect to an OPNSense firewall with certificate validation disabled</para>
|
||||
/// <code>Connect-OPNSense -Server "https://firewall.example.com" -ApiKey "your_api_key" -ApiSecret "your_api_secret" -SkipCertificateCheck</code>
|
||||
/// <para>This example connects to an OPNSense firewall at the specified URL using the provided API credentials, skipping certificate validation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommunications.Connect, "OPNSense")]
|
||||
[OutputType(typeof(void))]
|
||||
public class ConnectOPNSenseCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The URL of the OPNSense firewall.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The API key for authentication.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string ApiKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The API secret for authentication.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string ApiSecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Skips certificate validation when connecting to the OPNSense firewall.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter SkipCertificateCheck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Forces a new connection even if one already exists.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if already connected
|
||||
if (OPNSenseSession.IsConnected && !Force.IsPresent)
|
||||
{
|
||||
WriteWarning($"Already connected to {OPNSenseSession.BaseUrl}. Use -Force to reconnect.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispose existing connection if there is one
|
||||
OPNSenseSession.Current?.Dispose();
|
||||
|
||||
// Create a new logger
|
||||
var logger = new PowerShellLogger(this);
|
||||
|
||||
// Create a new API client
|
||||
var client = new OPNSenseApiClient(Server, ApiKey, ApiSecret, SkipCertificateCheck.IsPresent, logger);
|
||||
|
||||
// Set the current session
|
||||
OPNSenseSession.Current = client;
|
||||
|
||||
WriteVerbose($"Connected to OPNSense firewall at {Server}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"ConnectionFailed",
|
||||
ErrorCategory.ConnectionError,
|
||||
Server));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Connects an OPNSense firewall to a Tailscale network.</para>
|
||||
/// <para type="description">The Connect-OPNSenseTailscale cmdlet connects an OPNSense firewall to a Tailscale network using an authentication key.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Connect to Tailscale network</para>
|
||||
/// <code>Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456"</code>
|
||||
/// <para>This example connects the OPNSense firewall to a Tailscale network using the specified authentication key.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Connect to Tailscale network with auto-installation</para>
|
||||
/// <code>Connect-OPNSenseTailscale -AuthKey "tskey-auth-abcdef123456" -InstallIfMissing</code>
|
||||
/// <para>This example installs the Tailscale plugin if it's not already installed, then connects to the Tailscale network.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommunications.Connect, "OPNSenseTailscale", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class ConnectOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The Tailscale authentication key to use for connecting.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string AuthKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to install the Tailscale plugin if it's not already installed.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter InstallIfMissing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable Tailscale if it's not already enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableIfDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to start the Tailscale service if it's not already running.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter StartIfStopped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to advertise routes to the Tailscale network.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AdvertiseRoutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The subnet routes to advertise to the Tailscale network (e.g., "192.168.1.0/24", "10.0.0.0/8").</para>
|
||||
/// <para type="description">Multiple routes can be specified.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] SubnetRoutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to advertise this node as an exit node.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AdvertiseExitNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tailscaleService = new TailscaleService(ApiClient, Logger);
|
||||
|
||||
// Check if the plugin is installed
|
||||
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
|
||||
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!isInstalled)
|
||||
{
|
||||
if (!InstallIfMissing.IsPresent)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception("Tailscale plugin is not installed. Use -InstallIfMissing to install it."),
|
||||
"TailscalePluginNotInstalled",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Install Tailscale plugin"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose("Tailscale plugin is not installed. Installing...");
|
||||
var installTask = Task.Run(async () => await tailscaleService.InstallPluginAsync());
|
||||
var installResult = installTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!installResult)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception("Failed to install Tailscale plugin."),
|
||||
"TailscalePluginInstallFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose("Tailscale plugin installed successfully.");
|
||||
}
|
||||
|
||||
// Get current status
|
||||
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
var status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// Enable Tailscale if needed
|
||||
if (!status.Enabled && EnableIfDisabled.IsPresent)
|
||||
{
|
||||
WriteVerbose("Tailscale is disabled. Enabling...");
|
||||
|
||||
// Get current settings
|
||||
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
|
||||
var currentSettings = settingsTask.GetAwaiter().GetResult().General;
|
||||
|
||||
// Process subnet routes if provided
|
||||
string routesToAdvertise = currentSettings.RoutesToAdvertise;
|
||||
bool advertiseRoutes = AdvertiseRoutes.IsPresent || currentSettings.AdvertiseRoutes == "1";
|
||||
bool advertiseExitNode = AdvertiseExitNode.IsPresent || currentSettings.AdvertiseExitNode == "1";
|
||||
|
||||
if (SubnetRoutes != null && SubnetRoutes.Length > 0)
|
||||
{
|
||||
routesToAdvertise = string.Join(",", SubnetRoutes);
|
||||
WriteVerbose($"Advertising subnet routes: {routesToAdvertise}");
|
||||
|
||||
// If routes are specified but AdvertiseRoutes is not set, enable it automatically
|
||||
if (!advertiseRoutes)
|
||||
{
|
||||
WriteVerbose("Automatically enabling route advertisement because subnet routes were specified.");
|
||||
advertiseRoutes = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new settings with enabled flag
|
||||
var settings = new TailscaleSettings
|
||||
{
|
||||
Enabled = "1",
|
||||
AcceptDns = currentSettings.AcceptDns,
|
||||
AcceptRoutes = currentSettings.AcceptRoutes,
|
||||
AdvertiseExitNode = advertiseExitNode ? "1" : "0",
|
||||
AdvertiseRoutes = advertiseRoutes ? "1" : "0",
|
||||
RoutesToAdvertise = routesToAdvertise,
|
||||
Hostname = currentSettings.Hostname,
|
||||
LoginServer = currentSettings.LoginServer,
|
||||
Ssh = currentSettings.Ssh,
|
||||
Ephemeral = currentSettings.Ephemeral,
|
||||
ResetOnStart = currentSettings.ResetOnStart
|
||||
};
|
||||
|
||||
// Update settings
|
||||
var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
|
||||
|
||||
// Get updated status
|
||||
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
status = statusTask.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
// Start the service if needed
|
||||
if (!status.Running && StartIfStopped.IsPresent)
|
||||
{
|
||||
WriteVerbose("Tailscale service is not running. Starting...");
|
||||
var startTask = Task.Run(async () => await tailscaleService.StartServiceAsync());
|
||||
var startResult = startTask.GetAwaiter().GetResult();
|
||||
WriteVerbose($"Tailscale service started: {startResult.Status}");
|
||||
|
||||
// Get updated status
|
||||
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
status = statusTask.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
// Check if Tailscale is enabled and running
|
||||
if (!status.Enabled)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception("Tailscale is not enabled. Use -EnableIfDisabled to enable it."),
|
||||
"TailscaleNotEnabled",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!status.Running)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception("Tailscale service is not running. Use -StartIfStopped to start it."),
|
||||
"TailscaleNotRunning",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Connect to Tailscale network"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Connect to Tailscale
|
||||
WriteVerbose("Connecting to Tailscale network...");
|
||||
var connectTask = Task.Run(async () => await tailscaleService.ConnectAsync(AuthKey));
|
||||
var connectResult = connectTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Tailscale connection status: {connectResult.Status}");
|
||||
WriteVerbose($"Tailscale connection message: {connectResult.Message}");
|
||||
|
||||
// Get updated status
|
||||
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// Get interfaces
|
||||
var interfacesTask = Task.Run(async () => await tailscaleService.GetInterfacesAsync());
|
||||
var interfaces = interfacesTask.GetAwaiter().GetResult();
|
||||
|
||||
// Create result object
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("Status", status.Status));
|
||||
result.Properties.Add(new PSNoteProperty("Running", status.Running));
|
||||
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
|
||||
result.Properties.Add(new PSNoteProperty("ConnectionStatus", connectResult.Status));
|
||||
result.Properties.Add(new PSNoteProperty("ConnectionMessage", connectResult.Message));
|
||||
result.Properties.Add(new PSNoteProperty("Interfaces", interfaces.Interfaces));
|
||||
|
||||
WriteObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSOPNSenseAPI.Utilities;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Converts between different network notation formats.</para>
|
||||
/// <para type="description">The ConvertTo-OPNSenseNetworkNotation cmdlet converts between CIDR notation and subnet mask notation.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Convert CIDR to subnet mask</para>
|
||||
/// <code>ConvertTo-OPNSenseNetworkNotation -CIDR 24</code>
|
||||
/// <para>This example converts the CIDR prefix length 24 to the subnet mask 255.255.255.0.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Convert subnet mask to CIDR</para>
|
||||
/// <code>ConvertTo-OPNSenseNetworkNotation -SubnetMask "255.255.255.0"</code>
|
||||
/// <para>This example converts the subnet mask 255.255.255.0 to the CIDR prefix length 24.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Convert IP with CIDR to IP with subnet mask</para>
|
||||
/// <code>ConvertTo-OPNSenseNetworkNotation -IPWithCIDR "192.168.1.0/24"</code>
|
||||
/// <para>This example converts the IP with CIDR 192.168.1.0/24 to the IP with subnet mask 192.168.1.0 255.255.255.0.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 4: Convert IP with subnet mask to IP with CIDR</para>
|
||||
/// <code>ConvertTo-OPNSenseNetworkNotation -IPWithSubnetMask "192.168.1.0 255.255.255.0"</code>
|
||||
/// <para>This example converts the IP with subnet mask 192.168.1.0 255.255.255.0 to the IP with CIDR 192.168.1.0/24.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.ConvertTo, "OPNSenseNetworkNotation")]
|
||||
[OutputType(typeof(string), typeof(int))]
|
||||
public class ConvertToOPNSenseNetworkNotationCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The CIDR prefix length to convert to a subnet mask.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "FromCIDR")]
|
||||
[ValidateRange(0, 32)]
|
||||
public int? CIDR { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The subnet mask to convert to a CIDR prefix length.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "FromSubnetMask")]
|
||||
public string SubnetMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address with CIDR notation to convert to IP address with subnet mask.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "FromIPWithCIDR")]
|
||||
public string IPWithCIDR { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address with subnet mask to convert to IP address with CIDR notation.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "FromIPWithSubnetMask")]
|
||||
public string IPWithSubnetMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (ParameterSetName)
|
||||
{
|
||||
case "FromCIDR":
|
||||
if (CIDR.HasValue)
|
||||
{
|
||||
string subnetMask = NetworkUtility.GetSubnetMaskFromCIDR(CIDR.Value);
|
||||
WriteObject(subnetMask);
|
||||
}
|
||||
break;
|
||||
|
||||
case "FromSubnetMask":
|
||||
if (!string.IsNullOrEmpty(SubnetMask))
|
||||
{
|
||||
int cidr = NetworkUtility.GetCIDRFromSubnetMask(SubnetMask);
|
||||
WriteObject(cidr);
|
||||
}
|
||||
break;
|
||||
|
||||
case "FromIPWithCIDR":
|
||||
if (!string.IsNullOrEmpty(IPWithCIDR))
|
||||
{
|
||||
string[] parts = IPWithCIDR.Split('/');
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException($"Invalid IP with CIDR: {IPWithCIDR}. Expected format: 192.168.1.0/24"),
|
||||
"InvalidIPWithCIDR",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
string ip = parts[0];
|
||||
if (!int.TryParse(parts[1], out int cidr))
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException($"Invalid CIDR: {parts[1]}"),
|
||||
"InvalidCIDR",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
string subnetMask = NetworkUtility.GetSubnetMaskFromCIDR(cidr);
|
||||
WriteObject($"{ip} {subnetMask}");
|
||||
}
|
||||
break;
|
||||
|
||||
case "FromIPWithSubnetMask":
|
||||
if (!string.IsNullOrEmpty(IPWithSubnetMask))
|
||||
{
|
||||
string[] parts = IPWithSubnetMask.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException($"Invalid IP with subnet mask: {IPWithSubnetMask}. Expected format: 192.168.1.0 255.255.255.0"),
|
||||
"InvalidIPWithSubnetMask",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
string ip = parts[0];
|
||||
string subnetMask = parts[1];
|
||||
int cidr = NetworkUtility.GetCIDRFromSubnetMask(subnetMask);
|
||||
WriteObject($"{ip}/{cidr}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"ConversionError",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Disables a cron job on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Disable-OPNSenseCronJob cmdlet disables a cron job on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Disable a cron job</para>
|
||||
/// <code>Disable-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example disables a cron job by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Disable, "OPNSenseCronJob")]
|
||||
[OutputType(typeof(void))]
|
||||
public class DisableOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the cron job to disable.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await cronService.ToggleJobAsync(Uuid, false));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron job {Uuid} disabled: {result.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Disables a firewall rule on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Disable-OPNSenseFirewallRule cmdlet disables a firewall rule on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Disable a firewall rule</para>
|
||||
/// <code>Disable-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example disables a firewall rule by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Disable, "OPNSenseFirewallRule")]
|
||||
[OutputType(typeof(void))]
|
||||
public class DisableOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the firewall rule to disable.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await firewallService.ToggleRuleAsync(Uuid, false));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firewall rule {Uuid} disabled: {result.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Disables a plugin on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Disable-OPNSensePlugin cmdlet disables a plugin on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Disable a plugin</para>
|
||||
/// <code>Disable-OPNSensePlugin -Name "os-acme-client"</code>
|
||||
/// <para>This example disables the ACME client plugin on the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Disable, "OPNSensePlugin")]
|
||||
[OutputType(typeof(void))]
|
||||
public class DisableOPNSensePluginCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the plugin to disable.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var pluginService = new PluginService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await pluginService.DisablePluginAsync(Name));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Plugin {Name} disabled: {result.Status}");
|
||||
WriteObject($"Plugin {Name} disabled: {result.Status}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Disables Tailscale on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Disable-OPNSenseTailscale cmdlet disables Tailscale on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Disable Tailscale</para>
|
||||
/// <code>Disable-OPNSenseTailscale</code>
|
||||
/// <para>This example disables Tailscale on the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Disable Tailscale and stop the service</para>
|
||||
/// <code>Disable-OPNSenseTailscale -Stop</code>
|
||||
/// <para>This example disables Tailscale and stops the Tailscale service.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Disable, "OPNSenseTailscale", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class DisableOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to stop the Tailscale service after disabling it.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Stop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tailscaleService = new TailscaleService(ApiClient, Logger);
|
||||
|
||||
// Check if the plugin is installed
|
||||
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
|
||||
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!isInstalled)
|
||||
{
|
||||
WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current settings
|
||||
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
|
||||
var currentSettings = settingsTask.GetAwaiter().GetResult().General;
|
||||
|
||||
// Create new settings with disabled flag
|
||||
var settings = new TailscaleSettings
|
||||
{
|
||||
Enabled = "0",
|
||||
AcceptDns = currentSettings.AcceptDns,
|
||||
AcceptRoutes = currentSettings.AcceptRoutes,
|
||||
AdvertiseExitNode = currentSettings.AdvertiseExitNode,
|
||||
AdvertiseRoutes = currentSettings.AdvertiseRoutes,
|
||||
RoutesToAdvertise = currentSettings.RoutesToAdvertise,
|
||||
Hostname = currentSettings.Hostname,
|
||||
LoginServer = currentSettings.LoginServer,
|
||||
Ssh = currentSettings.Ssh,
|
||||
Ephemeral = currentSettings.Ephemeral,
|
||||
ResetOnStart = currentSettings.ResetOnStart
|
||||
};
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Disable Tailscale"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update settings
|
||||
var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
|
||||
|
||||
// Stop the service if requested
|
||||
if (Stop.IsPresent)
|
||||
{
|
||||
WriteVerbose("Stopping Tailscale service...");
|
||||
var stopTask = Task.Run(async () => await tailscaleService.StopServiceAsync());
|
||||
var stopResult = stopTask.GetAwaiter().GetResult();
|
||||
WriteVerbose($"Tailscale service stopped: {stopResult.Status}");
|
||||
}
|
||||
|
||||
// Get updated status
|
||||
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
var status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// Create result object
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
|
||||
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
|
||||
result.Properties.Add(new PSNoteProperty("Running", status.Running));
|
||||
result.Properties.Add(new PSNoteProperty("Status", status.Status));
|
||||
|
||||
WriteObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSOPNSenseAPI.Models;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Disconnects from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Disconnect-OPNSense cmdlet closes the connection to an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Disconnect from an OPNSense firewall</para>
|
||||
/// <code>Disconnect-OPNSense</code>
|
||||
/// <para>This example disconnects from the currently connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommunications.Disconnect, "OPNSense")]
|
||||
[OutputType(typeof(void))]
|
||||
public class DisconnectOPNSenseCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!OPNSenseSession.IsConnected)
|
||||
{
|
||||
WriteWarning("Not connected to any OPNSense firewall.");
|
||||
return;
|
||||
}
|
||||
|
||||
var baseUrl = OPNSenseSession.BaseUrl;
|
||||
OPNSenseSession.Current?.Dispose();
|
||||
OPNSenseSession.Current = null;
|
||||
|
||||
WriteVerbose($"Disconnected from OPNSense firewall at {baseUrl}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"DisconnectionFailed",
|
||||
ErrorCategory.ConnectionError,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Disconnects an OPNSense firewall from a Tailscale network.</para>
|
||||
/// <para type="description">The Disconnect-OPNSenseTailscale cmdlet disconnects an OPNSense firewall from a Tailscale network.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Disconnect from Tailscale network</para>
|
||||
/// <code>Disconnect-OPNSenseTailscale</code>
|
||||
/// <para>This example disconnects the OPNSense firewall from the Tailscale network.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommunications.Disconnect, "OPNSenseTailscale", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class DisconnectOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tailscaleService = new TailscaleService(ApiClient, Logger);
|
||||
|
||||
// Check if the plugin is installed
|
||||
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
|
||||
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!isInstalled)
|
||||
{
|
||||
WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current status
|
||||
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
var status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!status.Running)
|
||||
{
|
||||
WriteWarning("Tailscale service is not running.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Disconnect from Tailscale network"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Disconnect from Tailscale
|
||||
WriteVerbose("Disconnecting from Tailscale network...");
|
||||
var disconnectTask = Task.Run(async () => await tailscaleService.DisconnectAsync());
|
||||
var disconnectResult = disconnectTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Tailscale disconnection status: {disconnectResult.Status}");
|
||||
|
||||
// Get updated status
|
||||
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// Create result object
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("Status", status.Status));
|
||||
result.Properties.Add(new PSNoteProperty("Running", status.Running));
|
||||
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
|
||||
result.Properties.Add(new PSNoteProperty("DisconnectionStatus", disconnectResult.Status));
|
||||
|
||||
WriteObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Enables a cron job on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Enable-OPNSenseCronJob cmdlet enables a cron job on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Enable a cron job</para>
|
||||
/// <code>Enable-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example enables a cron job by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Enable, "OPNSenseCronJob")]
|
||||
[OutputType(typeof(void))]
|
||||
public class EnableOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the cron job to enable.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await cronService.ToggleJobAsync(Uuid, true));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron job {Uuid} enabled: {result.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Enables a firewall rule on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Enable-OPNSenseFirewallRule cmdlet enables a firewall rule on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Enable a firewall rule</para>
|
||||
/// <code>Enable-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example enables a firewall rule by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Enable, "OPNSenseFirewallRule")]
|
||||
[OutputType(typeof(void))]
|
||||
public class EnableOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the firewall rule to enable.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await firewallService.ToggleRuleAsync(Uuid, true));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firewall rule {Uuid} enabled: {result.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Enables a plugin on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Enable-OPNSensePlugin cmdlet enables a plugin on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Enable a plugin</para>
|
||||
/// <code>Enable-OPNSensePlugin -Name "os-acme-client"</code>
|
||||
/// <para>This example enables the ACME client plugin on the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Enable, "OPNSensePlugin")]
|
||||
[OutputType(typeof(void))]
|
||||
public class EnableOPNSensePluginCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the plugin to enable.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var pluginService = new PluginService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await pluginService.EnablePluginAsync(Name));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Plugin {Name} enabled: {result.Status}");
|
||||
WriteObject($"Plugin {Name} enabled: {result.Status}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Enables and configures Tailscale on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Enable-OPNSenseTailscale cmdlet enables and configures Tailscale on an OPNSense firewall. If the Tailscale plugin is not installed, it will be installed automatically.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Enable Tailscale with default settings</para>
|
||||
/// <code>Enable-OPNSenseTailscale</code>
|
||||
/// <para>This example enables Tailscale with default settings.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Enable Tailscale with custom settings</para>
|
||||
/// <code>Enable-OPNSenseTailscale -AcceptDns -AcceptRoutes -Hostname "opnsense-firewall"</code>
|
||||
/// <para>This example enables Tailscale and configures it to accept DNS and routes from Tailscale, and sets the hostname.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Enable, "OPNSenseTailscale", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class EnableOPNSenseTailscaleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to accept DNS configuration from Tailscale.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AcceptDns { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to accept routes from Tailscale.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AcceptRoutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to advertise this node as an exit node.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AdvertiseExitNode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to advertise routes to the Tailscale network.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AdvertiseRoutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The routes to advertise to the Tailscale network (e.g., "192.168.1.0/24,10.0.0.0/8").</para>
|
||||
/// <para type="description">Multiple routes should be comma-separated.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] SubnetRoutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The hostname to use for this node in the Tailscale network.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Hostname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The login server to use (leave empty for default).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string LoginServer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable SSH access through Tailscale.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableSsh { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to use an ephemeral node key (node will disappear from network when restarted).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Ephemeral { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to reset the Tailscale state on service start.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter ResetOnStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to start the Tailscale service after enabling it.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Start { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to restart the Tailscale service if it's already running.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Restart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to force installation of the Tailscale plugin if it's not already installed.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tailscaleService = new TailscaleService(ApiClient, Logger);
|
||||
|
||||
// Check if the plugin is installed
|
||||
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
|
||||
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!isInstalled)
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Install Tailscale plugin"))
|
||||
{
|
||||
WriteWarning("Tailscale plugin is not installed and -Force was not specified. Operation cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose("Tailscale plugin is not installed. Installing...");
|
||||
var installTask = Task.Run(async () => await tailscaleService.InstallPluginAsync());
|
||||
var installResult = installTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!installResult)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception("Failed to install Tailscale plugin."),
|
||||
"TailscalePluginInstallFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteVerbose("Tailscale plugin installed successfully.");
|
||||
}
|
||||
|
||||
// Get current settings
|
||||
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
|
||||
var currentSettings = settingsTask.GetAwaiter().GetResult().General;
|
||||
|
||||
// Process subnet routes if provided
|
||||
string routesToAdvertise = currentSettings.RoutesToAdvertise;
|
||||
if (SubnetRoutes != null && SubnetRoutes.Length > 0)
|
||||
{
|
||||
routesToAdvertise = string.Join(",", SubnetRoutes);
|
||||
WriteVerbose($"Advertising subnet routes: {routesToAdvertise}");
|
||||
|
||||
// If routes are specified but AdvertiseRoutes is not set, enable it automatically
|
||||
if (!AdvertiseRoutes.IsPresent)
|
||||
{
|
||||
WriteVerbose("Automatically enabling route advertisement because subnet routes were specified.");
|
||||
AdvertiseRoutes = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new settings
|
||||
var settings = new TailscaleSettings
|
||||
{
|
||||
Enabled = "1",
|
||||
AcceptDns = AcceptDns.IsPresent ? "1" : "0",
|
||||
AcceptRoutes = AcceptRoutes.IsPresent ? "1" : "0",
|
||||
AdvertiseExitNode = AdvertiseExitNode.IsPresent ? "1" : "0",
|
||||
AdvertiseRoutes = AdvertiseRoutes.IsPresent ? "1" : "0",
|
||||
RoutesToAdvertise = routesToAdvertise,
|
||||
Hostname = Hostname ?? currentSettings.Hostname,
|
||||
LoginServer = LoginServer ?? currentSettings.LoginServer,
|
||||
Ssh = EnableSsh.IsPresent ? "1" : "0",
|
||||
Ephemeral = Ephemeral.IsPresent ? "1" : "0",
|
||||
ResetOnStart = ResetOnStart.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
if (!ShouldProcess("OPNSense firewall", "Enable and configure Tailscale"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update settings
|
||||
var updateTask = Task.Run(async () => await tailscaleService.UpdateSettingsAsync(settings));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Tailscale settings updated: {updateResult.Result}");
|
||||
|
||||
// Get current status
|
||||
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
var status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// Start or restart the service if requested
|
||||
if (Restart.IsPresent || (Start.IsPresent && !status.Running))
|
||||
{
|
||||
if (status.Running)
|
||||
{
|
||||
if (Restart.IsPresent)
|
||||
{
|
||||
WriteVerbose("Restarting Tailscale service...");
|
||||
var restartTask = Task.Run(async () => await tailscaleService.RestartServiceAsync());
|
||||
var restartResult = restartTask.GetAwaiter().GetResult();
|
||||
WriteVerbose($"Tailscale service restarted: {restartResult.Status}");
|
||||
}
|
||||
}
|
||||
else if (Start.IsPresent)
|
||||
{
|
||||
WriteVerbose("Starting Tailscale service...");
|
||||
var startTask = Task.Run(async () => await tailscaleService.StartServiceAsync());
|
||||
var startResult = startTask.GetAwaiter().GetResult();
|
||||
WriteVerbose($"Tailscale service started: {startResult.Status}");
|
||||
}
|
||||
}
|
||||
|
||||
// Get updated status
|
||||
statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// Create result object
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
|
||||
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
|
||||
result.Properties.Add(new PSNoteProperty("Running", status.Running));
|
||||
result.Properties.Add(new PSNoteProperty("Status", status.Status));
|
||||
result.Properties.Add(new PSNoteProperty("Settings", settings));
|
||||
|
||||
WriteObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Exports the OPNSense firewall configuration.</para>
|
||||
/// <para type="description">The Export-OPNSenseConfig cmdlet exports the OPNSense firewall configuration to a file.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Export the configuration to a file</para>
|
||||
/// <code>Export-OPNSenseConfig -Path "C:\Backups\opnsense-config.xml"</code>
|
||||
/// <para>This example exports the OPNSense firewall configuration to a file.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Export, "OPNSenseConfig")]
|
||||
[OutputType(typeof(void))]
|
||||
public class ExportOPNSenseConfigCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The path to save the configuration file.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Overwrites the file if it exists.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if the file exists
|
||||
if (File.Exists(Path) && !Force.IsPresent)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new IOException($"The file '{Path}' already exists. Use -Force to overwrite."),
|
||||
"FileExists",
|
||||
ErrorCategory.ResourceExists,
|
||||
Path));
|
||||
return;
|
||||
}
|
||||
|
||||
var configService = new ConfigService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await configService.ExportConfigAsync());
|
||||
var configContent = task.GetAwaiter().GetResult();
|
||||
|
||||
// Create the directory if it doesn't exist
|
||||
var directory = System.IO.Path.GetDirectoryName(Path);
|
||||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
// Write the configuration to the file
|
||||
File.WriteAllBytes(Path, configContent);
|
||||
|
||||
WriteVerbose($"Exported configuration to {Path}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets aliases from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseAlias cmdlet retrieves aliases from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all aliases</para>
|
||||
/// <code>Get-OPNSenseAlias</code>
|
||||
/// <para>This example retrieves all aliases from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific alias by UUID</para>
|
||||
/// <code>Get-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific alias by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Get aliases by type</para>
|
||||
/// <code>Get-OPNSenseAlias | Where-Object { $_.Type -eq "host" }</code>
|
||||
/// <para>This example retrieves all host aliases.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseAlias")]
|
||||
[OutputType(typeof(Alias), typeof(AliasDetail))]
|
||||
public class GetOPNSenseAliasCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the alias to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the alias to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByName")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The type of aliases to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("host", "network", "port", "url", "urltable", "geoip", "networkgroup", "mac", "interface", "dynipv6host", "internal", "external")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var aliasService = new AliasService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await aliasService.GetAliasesAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
// Filter by name if specified
|
||||
if (ParameterSetName == "ByName")
|
||||
{
|
||||
var filteredByName = result.Rows.FindAll(a => a.Name.Equals(Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// Further filter by type if specified
|
||||
if (!string.IsNullOrEmpty(Type))
|
||||
{
|
||||
var filteredByType = filteredByName.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
|
||||
WriteObject(filteredByType, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteObject(filteredByName, true);
|
||||
}
|
||||
}
|
||||
// Filter by type if specified
|
||||
else if (!string.IsNullOrEmpty(Type))
|
||||
{
|
||||
var filteredByType = result.Rows.FindAll(a => a.Type.Equals(Type, StringComparison.OrdinalIgnoreCase));
|
||||
WriteObject(filteredByType, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets configuration backups from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseConfigBackup cmdlet retrieves configuration backups from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all configuration backups</para>
|
||||
/// <code>Get-OPNSenseConfigBackup</code>
|
||||
/// <para>This example retrieves all configuration backups from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseConfigBackup")]
|
||||
[OutputType(typeof(ConfigBackup))]
|
||||
public class GetOPNSenseConfigBackupCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configService = new ConfigService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await configService.GetConfigBackupsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteObject(result.Backups, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSOPNSenseAPI.Models;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets information about the current OPNSense connection.</para>
|
||||
/// <para type="description">The Get-OPNSenseConnection cmdlet retrieves information about the current connection to an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get the current connection information</para>
|
||||
/// <code>Get-OPNSenseConnection</code>
|
||||
/// <para>This example retrieves information about the current connection to an OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseConnection")]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class GetOPNSenseConnectionCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!OPNSenseSession.IsConnected)
|
||||
{
|
||||
WriteWarning("Not connected to any OPNSense firewall.");
|
||||
return;
|
||||
}
|
||||
|
||||
var connectionInfo = new PSObject();
|
||||
connectionInfo.Properties.Add(new PSNoteProperty("Server", OPNSenseSession.BaseUrl));
|
||||
connectionInfo.Properties.Add(new PSNoteProperty("Connected", OPNSenseSession.IsConnected));
|
||||
|
||||
WriteObject(connectionInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"GetConnectionFailed",
|
||||
ErrorCategory.ConnectionError,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets cron jobs from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseCronJob cmdlet retrieves cron jobs from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all cron jobs</para>
|
||||
/// <code>Get-OPNSenseCronJob</code>
|
||||
/// <para>This example retrieves all cron jobs from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific cron job by UUID</para>
|
||||
/// <code>Get-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific cron job by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseCronJob")]
|
||||
[OutputType(typeof(CronJob), typeof(CronJobDetail))]
|
||||
public class GetOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the cron job to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await cronService.GetJobAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Job);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await cronService.GetJobsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DHCP leases from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDHCPLease cmdlet retrieves DHCP leases from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all DHCP leases</para>
|
||||
/// <code>Get-OPNSenseDHCPLease</code>
|
||||
/// <para>This example retrieves all DHCP leases from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get active DHCP leases</para>
|
||||
/// <code>Get-OPNSenseDHCPLease | Where-Object { $_.State -eq "active" }</code>
|
||||
/// <para>This example retrieves all active DHCP leases from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPLease")]
|
||||
[OutputType(typeof(DHCPLease))]
|
||||
public class GetOPNSenseDHCPLeaseCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await dhcpService.GetLeasesAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DHCP options from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDHCPOption cmdlet retrieves DHCP options from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all DHCP options for an interface</para>
|
||||
/// <code>Get-OPNSenseDHCPOption -Interface "lan"</code>
|
||||
/// <para>This example retrieves all DHCP options for the LAN interface.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific DHCP option by UUID</para>
|
||||
/// <code>Get-OPNSenseDHCPOption -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific DHCP option by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPOption")]
|
||||
[OutputType(typeof(DHCPOption), typeof(DHCPOptionDetail))]
|
||||
public class GetOPNSenseDHCPOptionCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface name.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DHCP option to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 1, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Option);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await dhcpService.GetOptionsAsync(Interface));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DHCP servers from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDHCPServer cmdlet retrieves DHCP servers from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all DHCP servers</para>
|
||||
/// <code>Get-OPNSenseDHCPServer</code>
|
||||
/// <para>This example retrieves all DHCP servers from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific DHCP server by interface</para>
|
||||
/// <code>Get-OPNSenseDHCPServer -Interface "lan"</code>
|
||||
/// <para>This example retrieves the DHCP server for the LAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPServer")]
|
||||
[OutputType(typeof(PSObject), typeof(DHCPServerDetail))]
|
||||
public class GetOPNSenseDHCPServerCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface to get the DHCP server for.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByInterface")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByInterface")
|
||||
{
|
||||
var task = Task.Run(async () => await dhcpService.GetServerAsync(Interface));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Server);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await dhcpService.GetServersAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
foreach (var kvp in result.Servers.Interfaces)
|
||||
{
|
||||
var server = new PSObject();
|
||||
server.Properties.Add(new PSNoteProperty("Interface", kvp.Key));
|
||||
server.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
|
||||
server.Properties.Add(new PSNoteProperty("RangeFrom", kvp.Value.RangeFrom));
|
||||
server.Properties.Add(new PSNoteProperty("RangeTo", kvp.Value.RangeTo));
|
||||
server.Properties.Add(new PSNoteProperty("DefaultLeaseTime", kvp.Value.DefaultLeaseTime));
|
||||
server.Properties.Add(new PSNoteProperty("MaxLeaseTime", kvp.Value.MaxLeaseTime));
|
||||
server.Properties.Add(new PSNoteProperty("Domain", kvp.Value.Domain));
|
||||
server.Properties.Add(new PSNoteProperty("DnsServers", kvp.Value.DnsServers));
|
||||
server.Properties.Add(new PSNoteProperty("Gateway", kvp.Value.Gateway));
|
||||
|
||||
WriteObject(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DHCP static mappings from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDHCPStaticMapping cmdlet retrieves DHCP static mappings from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all static mappings for an interface</para>
|
||||
/// <code>Get-OPNSenseDHCPStaticMapping -Interface "lan"</code>
|
||||
/// <para>This example retrieves all static mappings for the LAN interface.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific static mapping by UUID</para>
|
||||
/// <code>Get-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific static mapping by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDHCPStaticMapping")]
|
||||
[OutputType(typeof(DHCPStaticMapping), typeof(DHCPStaticMappingDetail))]
|
||||
public class GetOPNSenseDHCPStaticMappingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface to get static mappings for.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the static mapping to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 1, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Mapping);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await dhcpService.GetStaticMappingsAsync(Interface));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets the DNS forwarding configuration from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDNSForwarding cmdlet retrieves the DNS forwarding configuration from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get DNS forwarding configuration</para>
|
||||
/// <code>Get-OPNSenseDNSForwarding</code>
|
||||
/// <para>This example retrieves the DNS forwarding configuration from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSForwarding")]
|
||||
[OutputType(typeof(DNSForwardingConfig))]
|
||||
public class GetOPNSenseDNSForwardingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await dnsService.GetDNSForwardingAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteObject(result.Forward);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DNS forwarding hosts from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDNSForwardingHost cmdlet retrieves DNS forwarding hosts from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all DNS forwarding hosts</para>
|
||||
/// <code>Get-OPNSenseDNSForwardingHost</code>
|
||||
/// <para>This example retrieves all DNS forwarding hosts from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific DNS forwarding host by UUID</para>
|
||||
/// <code>Get-OPNSenseDNSForwardingHost -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific DNS forwarding host by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSForwardingHost")]
|
||||
[OutputType(typeof(DNSForwardingHost), typeof(DNSForwardingHostDetail))]
|
||||
public class GetOPNSenseDNSForwardingHostCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DNS forwarding host to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await dnsService.GetDNSForwardingHostAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Host);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await dnsService.GetDNSForwardingHostsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DNS overrides from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDNSOverride cmdlet retrieves DNS overrides from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all DNS overrides</para>
|
||||
/// <code>Get-OPNSenseDNSOverride</code>
|
||||
/// <para>This example retrieves all DNS overrides from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific DNS override by UUID</para>
|
||||
/// <code>Get-OPNSenseDNSOverride -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific DNS override by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSOverride")]
|
||||
[OutputType(typeof(DNSOverride), typeof(DNSOverrideDetail))]
|
||||
public class GetOPNSenseDNSOverrideCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DNS override to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await dnsService.GetDNSOverrideAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Host);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await dnsService.GetDNSOverridesAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets DNS server configuration from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseDNSServer cmdlet retrieves DNS server configuration from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get DNS server configuration</para>
|
||||
/// <code>Get-OPNSenseDNSServer</code>
|
||||
/// <para>This example retrieves the DNS server configuration from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseDNSServer")]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class GetOPNSenseDNSServerCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await dnsService.GetDNSConfigAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
var dnsConfig = new PSObject();
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("Enabled", result.Unbound.Enabled == "1"));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("Port", result.Unbound.Port));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("Interfaces", result.Unbound.Interfaces));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("Forwarding", result.Unbound.Forwarding == "1"));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("Forwarders", result.Unbound.Forwarders));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcp", result.Unbound.RegisterDhcp == "1"));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpDomain", result.Unbound.RegisterDhcpDomain));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("RegisterDhcpStatic", result.Unbound.RegisterDhcpStatic == "1"));
|
||||
dnsConfig.Properties.Add(new PSNoteProperty("ActiveInterfaces", result.Unbound.ActiveInterfaces));
|
||||
|
||||
WriteObject(dnsConfig);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets firewall rules from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseFirewallRule cmdlet retrieves firewall rules from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all firewall rules</para>
|
||||
/// <code>Get-OPNSenseFirewallRule</code>
|
||||
/// <para>This example retrieves all firewall rules from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific firewall rule by UUID</para>
|
||||
/// <code>Get-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific firewall rule by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Search for firewall rules by description</para>
|
||||
/// <code>Get-OPNSenseFirewallRule -SearchPhrase "Allow HTTP"</code>
|
||||
/// <para>This example searches for firewall rules with a description containing "Allow HTTP".</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseFirewallRule")]
|
||||
[OutputType(typeof(FirewallRule), typeof(FirewallRuleDetails))]
|
||||
public class GetOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the firewall rule to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The search phrase to filter rules by.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "BySearch")]
|
||||
public string SearchPhrase { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The page number to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "BySearch")]
|
||||
[ValidateRange(1, int.MaxValue)]
|
||||
public int Page { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The number of rules to retrieve per page.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "BySearch")]
|
||||
[ValidateRange(1, 1000)]
|
||||
public int RowCount { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await firewallService.GetRulesAsync(SearchPhrase, Page, RowCount));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets firmware information from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseFirmware cmdlet retrieves firmware information from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get firmware status</para>
|
||||
/// <code>Get-OPNSenseFirmware</code>
|
||||
/// <para>This example retrieves the firmware status from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get firmware changelog</para>
|
||||
/// <code>Get-OPNSenseFirmware -Changelog</code>
|
||||
/// <para>This example retrieves the firmware changelog from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Get firmware audit</para>
|
||||
/// <code>Get-OPNSenseFirmware -Audit</code>
|
||||
/// <para>This example retrieves the firmware audit from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseFirmware")]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class GetOPNSenseFirmwareCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Gets the firmware changelog.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "Changelog")]
|
||||
public SwitchParameter Changelog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Gets the firmware audit.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "Audit")]
|
||||
public SwitchParameter Audit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Gets the firmware health.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "Health")]
|
||||
public SwitchParameter Health { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Checks for firmware updates.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "Check")]
|
||||
public SwitchParameter Check { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
switch (ParameterSetName)
|
||||
{
|
||||
case "Changelog":
|
||||
var changelogTask = Task.Run(async () => await firmwareService.GetChangelogAsync());
|
||||
var changelogResult = changelogTask.GetAwaiter().GetResult();
|
||||
WriteObject(changelogResult.Changelog);
|
||||
break;
|
||||
|
||||
case "Audit":
|
||||
var auditTask = Task.Run(async () => await firmwareService.GetAuditAsync());
|
||||
var auditResult = auditTask.GetAwaiter().GetResult();
|
||||
WriteObject(auditResult.Audit, true);
|
||||
break;
|
||||
|
||||
case "Health":
|
||||
var healthTask = Task.Run(async () => await firmwareService.GetHealthAsync());
|
||||
var healthResult = healthTask.GetAwaiter().GetResult();
|
||||
WriteObject(healthResult.Health);
|
||||
break;
|
||||
|
||||
case "Check":
|
||||
var checkTask = Task.Run(async () => await firmwareService.CheckForUpdatesAsync());
|
||||
var checkResult = checkTask.GetAwaiter().GetResult();
|
||||
WriteObject($"Check for updates: {checkResult.Status}");
|
||||
break;
|
||||
|
||||
default:
|
||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
var firmware = new PSObject();
|
||||
firmware.Properties.Add(new PSNoteProperty("Status", statusResult.Status));
|
||||
firmware.Properties.Add(new PSNoteProperty("Connection", statusResult.Connection));
|
||||
firmware.Properties.Add(new PSNoteProperty("DownloadSize", statusResult.DownloadSize));
|
||||
firmware.Properties.Add(new PSNoteProperty("LastCheck", statusResult.LastCheck));
|
||||
firmware.Properties.Add(new PSNoteProperty("UpgradeMessage", statusResult.UpgradeMessage));
|
||||
firmware.Properties.Add(new PSNoteProperty("Updates", statusResult.Updates));
|
||||
|
||||
WriteObject(firmware);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets gateways from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseGateway cmdlet retrieves gateways from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all gateways</para>
|
||||
/// <code>Get-OPNSenseGateway</code>
|
||||
/// <para>This example retrieves all gateways from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific gateway by UUID</para>
|
||||
/// <code>Get-OPNSenseGateway -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific gateway by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseGateway")]
|
||||
[OutputType(typeof(Gateway), typeof(GatewayDetail))]
|
||||
public class GetOPNSenseGatewayCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the gateway to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to include status information for the gateways.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter IncludeStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await gatewayService.GetGatewayAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Gateway);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await gatewayService.GetGatewaysAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
if (IncludeStatus.IsPresent)
|
||||
{
|
||||
var statusTask = Task.Run(async () => await gatewayService.GetGatewayStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
foreach (var gateway in result.Rows)
|
||||
{
|
||||
var gatewayWithStatus = new PSObject();
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Uuid", gateway.Uuid));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Name", gateway.Name));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Interface", gateway.Interface));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("IpAddress", gateway.IpAddress));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("MonitorIp", gateway.MonitorIp));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Description", gateway.Description));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("IsDefault", gateway.IsDefault == "1"));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Disabled", gateway.Disabled == "1"));
|
||||
|
||||
if (statusResult.Items.ContainsKey(gateway.Name))
|
||||
{
|
||||
var status = statusResult.Items[gateway.Name];
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Status", status.Status));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("RTT", status.RTT));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("StdDev", status.StdDev));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Loss", status.Loss));
|
||||
}
|
||||
else
|
||||
{
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Status", "Unknown"));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("RTT", "N/A"));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("StdDev", "N/A"));
|
||||
gatewayWithStatus.Properties.Add(new PSNoteProperty("Loss", "N/A"));
|
||||
}
|
||||
|
||||
WriteObject(gatewayWithStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets interfaces from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseInterface cmdlet retrieves interfaces from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all interfaces</para>
|
||||
/// <code>Get-OPNSenseInterface</code>
|
||||
/// <para>This example retrieves all interfaces from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific interface by name</para>
|
||||
/// <code>Get-OPNSenseInterface -Name "wan"</code>
|
||||
/// <para>This example retrieves a specific interface by its name.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseInterface")]
|
||||
[OutputType(typeof(InterfaceInfo), typeof(InterfaceDetail))]
|
||||
public class GetOPNSenseInterfaceCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the interface to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByName")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByName")
|
||||
{
|
||||
var task = Task.Run(async () => await interfaceService.GetInterfaceDetailAsync(Name));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Interface);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await interfaceService.GetInterfacesAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Interfaces, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets interface statistics from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseInterfaceStatistics cmdlet retrieves interface statistics from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all interface statistics</para>
|
||||
/// <code>Get-OPNSenseInterfaceStatistics</code>
|
||||
/// <para>This example retrieves statistics for all interfaces from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get statistics for a specific interface</para>
|
||||
/// <code>Get-OPNSenseInterfaceStatistics | Where-Object { $_.Name -eq "wan" }</code>
|
||||
/// <para>This example retrieves statistics for the WAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseInterfaceStatistics")]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class GetOPNSenseInterfaceStatisticsCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await interfaceService.GetInterfaceStatisticsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
foreach (var kvp in result.Statistics)
|
||||
{
|
||||
var stats = new PSObject();
|
||||
stats.Properties.Add(new PSNoteProperty("Name", kvp.Key));
|
||||
stats.Properties.Add(new PSNoteProperty("InPackets", kvp.Value.InPackets));
|
||||
stats.Properties.Add(new PSNoteProperty("InBytes", kvp.Value.InBytes));
|
||||
stats.Properties.Add(new PSNoteProperty("InErrors", 0));
|
||||
stats.Properties.Add(new PSNoteProperty("OutPackets", kvp.Value.OutPackets));
|
||||
stats.Properties.Add(new PSNoteProperty("OutBytes", kvp.Value.OutBytes));
|
||||
stats.Properties.Add(new PSNoteProperty("OutErrors", 0));
|
||||
stats.Properties.Add(new PSNoteProperty("Collisions", 0));
|
||||
|
||||
WriteObject(stats);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets plugins from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSensePlugin cmdlet retrieves plugins from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all installed plugins</para>
|
||||
/// <code>Get-OPNSensePlugin -Installed</code>
|
||||
/// <para>This example retrieves all installed plugins from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get all available plugins</para>
|
||||
/// <code>Get-OPNSensePlugin -Available</code>
|
||||
/// <para>This example retrieves all available plugins from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Get all plugins</para>
|
||||
/// <code>Get-OPNSensePlugin</code>
|
||||
/// <para>This example retrieves all installed and available plugins from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSensePlugin")]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class GetOPNSensePluginCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Gets only installed plugins.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "Installed")]
|
||||
public SwitchParameter Installed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Gets only available plugins.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, ParameterSetName = "Available")]
|
||||
public SwitchParameter Available { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var pluginService = new PluginService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await pluginService.GetPluginsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
if (ParameterSetName == "Installed" || ParameterSetName == "")
|
||||
{
|
||||
foreach (var kvp in result.Installed)
|
||||
{
|
||||
var plugin = new PSObject();
|
||||
plugin.Properties.Add(new PSNoteProperty("Name", kvp.Key));
|
||||
plugin.Properties.Add(new PSNoteProperty("Version", kvp.Value.Version));
|
||||
plugin.Properties.Add(new PSNoteProperty("Comment", kvp.Value.Comment));
|
||||
plugin.Properties.Add(new PSNoteProperty("Repository", kvp.Value.Repository));
|
||||
plugin.Properties.Add(new PSNoteProperty("Origin", kvp.Value.Origin));
|
||||
plugin.Properties.Add(new PSNoteProperty("License", kvp.Value.License));
|
||||
plugin.Properties.Add(new PSNoteProperty("FlatSize", kvp.Value.FlatSize));
|
||||
plugin.Properties.Add(new PSNoteProperty("Locked", kvp.Value.Locked == "1"));
|
||||
plugin.Properties.Add(new PSNoteProperty("Enabled", kvp.Value.Enabled == "1"));
|
||||
plugin.Properties.Add(new PSNoteProperty("Status", "Installed"));
|
||||
|
||||
WriteObject(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
if (ParameterSetName == "Available" || ParameterSetName == "")
|
||||
{
|
||||
foreach (var kvp in result.Available)
|
||||
{
|
||||
// Skip if the plugin is already installed
|
||||
if (result.Installed.ContainsKey(kvp.Key))
|
||||
continue;
|
||||
|
||||
var plugin = new PSObject();
|
||||
plugin.Properties.Add(new PSNoteProperty("Name", kvp.Key));
|
||||
plugin.Properties.Add(new PSNoteProperty("Version", kvp.Value.Version));
|
||||
plugin.Properties.Add(new PSNoteProperty("Comment", kvp.Value.Comment));
|
||||
plugin.Properties.Add(new PSNoteProperty("Repository", kvp.Value.Repository));
|
||||
plugin.Properties.Add(new PSNoteProperty("Origin", kvp.Value.Origin));
|
||||
plugin.Properties.Add(new PSNoteProperty("License", kvp.Value.License));
|
||||
plugin.Properties.Add(new PSNoteProperty("FlatSize", kvp.Value.FlatSize));
|
||||
plugin.Properties.Add(new PSNoteProperty("Status", "Available"));
|
||||
|
||||
WriteObject(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Models;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets port forwarding rules from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSensePortForwardingRule cmdlet gets port forwarding rules from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Get all port forwarding rules</para>
|
||||
/// <code>Get-OPNSensePortForwardingRule</code>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Get a specific port forwarding rule by UUID</para>
|
||||
/// <code>Get-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"</code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSensePortForwardingRule")]
|
||||
[OutputType(typeof(PortForwardingRule))]
|
||||
public class GetOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the port forwarding rule to get. If not specified, all rules are returned.</para>
|
||||
/// </summary>
|
||||
[Parameter(Position = 0, Mandatory = false)]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
var portForwardingService = new PortForwardingService(SessionState.ApiClient);
|
||||
|
||||
if (!string.IsNullOrEmpty(Uuid))
|
||||
{
|
||||
// Get a specific rule
|
||||
var rule = Task.Run(async () => await portForwardingService.GetPortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
|
||||
if (rule != null)
|
||||
{
|
||||
WriteObject(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteWarning($"Port forwarding rule with UUID '{Uuid}' not found.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get all rules
|
||||
var rules = Task.Run(async () => await portForwardingService.GetPortForwardingRulesAsync()).GetAwaiter().GetResult();
|
||||
WriteObject(rules, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets routes from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseRoute cmdlet retrieves routes from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all routes</para>
|
||||
/// <code>Get-OPNSenseRoute</code>
|
||||
/// <para>This example retrieves all routes from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific route by UUID</para>
|
||||
/// <code>Get-OPNSenseRoute -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific route by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseRoute")]
|
||||
[OutputType(typeof(Route), typeof(RouteDetail))]
|
||||
public class GetOPNSenseRouteCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the route to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var routeService = new RouteService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await routeService.GetRouteAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Route);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await routeService.GetRoutesAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets the system DNS configuration from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseSystemDNS cmdlet retrieves the system DNS configuration from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get system DNS configuration</para>
|
||||
/// <code>Get-OPNSenseSystemDNS</code>
|
||||
/// <para>This example retrieves the system DNS configuration from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseSystemDNS")]
|
||||
[OutputType(typeof(SystemDNSConfig))]
|
||||
public class GetOPNSenseSystemDNSCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var systemDNSService = new SystemDNSService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await systemDNSService.GetSystemDNSAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteObject(result.System);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets the status of Tailscale on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseTailscaleStatus cmdlet retrieves the current status of Tailscale on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get Tailscale status</para>
|
||||
/// <code>Get-OPNSenseTailscaleStatus</code>
|
||||
/// <para>This example retrieves the current status of Tailscale on the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseTailscaleStatus")]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class GetOPNSenseTailscaleStatusCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to include detailed information about Tailscale interfaces.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter IncludeInterfaces { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to include Tailscale settings.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter IncludeSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tailscaleService = new TailscaleService(ApiClient, Logger);
|
||||
|
||||
// Check if the plugin is installed
|
||||
var isInstalledTask = Task.Run(async () => await tailscaleService.IsPluginInstalledAsync());
|
||||
var isInstalled = isInstalledTask.GetAwaiter().GetResult();
|
||||
|
||||
if (!isInstalled)
|
||||
{
|
||||
WriteWarning("Tailscale plugin is not installed on the OPNSense firewall.");
|
||||
|
||||
var statusResult = new PSObject();
|
||||
statusResult.Properties.Add(new PSNoteProperty("PluginInstalled", false));
|
||||
statusResult.Properties.Add(new PSNoteProperty("Running", false));
|
||||
statusResult.Properties.Add(new PSNoteProperty("Enabled", false));
|
||||
statusResult.Properties.Add(new PSNoteProperty("Status", "Plugin not installed"));
|
||||
|
||||
WriteObject(statusResult);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the status
|
||||
var statusTask = Task.Run(async () => await tailscaleService.GetStatusAsync());
|
||||
var status = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("PluginInstalled", true));
|
||||
result.Properties.Add(new PSNoteProperty("Running", status.Running));
|
||||
result.Properties.Add(new PSNoteProperty("Enabled", status.Enabled));
|
||||
result.Properties.Add(new PSNoteProperty("Status", status.Status));
|
||||
|
||||
// Get interfaces if requested
|
||||
if (IncludeInterfaces.IsPresent)
|
||||
{
|
||||
var interfacesTask = Task.Run(async () => await tailscaleService.GetInterfacesAsync());
|
||||
var interfaces = interfacesTask.GetAwaiter().GetResult();
|
||||
|
||||
result.Properties.Add(new PSNoteProperty("Interfaces", interfaces.Interfaces));
|
||||
}
|
||||
|
||||
// Get settings if requested
|
||||
if (IncludeSettings.IsPresent)
|
||||
{
|
||||
var settingsTask = Task.Run(async () => await tailscaleService.GetSettingsAsync());
|
||||
var settings = settingsTask.GetAwaiter().GetResult();
|
||||
|
||||
result.Properties.Add(new PSNoteProperty("Settings", settings.General));
|
||||
}
|
||||
|
||||
WriteObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets users from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseUser cmdlet retrieves users from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all users</para>
|
||||
/// <code>Get-OPNSenseUser</code>
|
||||
/// <para>This example retrieves all users from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific user by UUID</para>
|
||||
/// <code>Get-OPNSenseUser -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific user by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseUser")]
|
||||
[OutputType(typeof(User), typeof(UserDetail))]
|
||||
public class GetOPNSenseUserCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the user to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await userService.GetUserAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.User);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await userService.GetUsersAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Gets VLANs from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Get-OPNSenseVLAN cmdlet retrieves VLANs from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get all VLANs</para>
|
||||
/// <code>Get-OPNSenseVLAN</code>
|
||||
/// <para>This example retrieves all VLANs from the connected OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Get a specific VLAN by UUID</para>
|
||||
/// <code>Get-OPNSenseVLAN -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example retrieves a specific VLAN by its UUID.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Get, "OPNSenseVLAN")]
|
||||
[OutputType(typeof(VLAN), typeof(VLANDetail))]
|
||||
public class GetOPNSenseVLANCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the VLAN to retrieve.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false, Position = 0, ParameterSetName = "ByUuid")]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
if (ParameterSetName == "ByUuid")
|
||||
{
|
||||
var task = Task.Run(async () => await interfaceService.GetVLANAsync(Uuid));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Vlan);
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = Task.Run(async () => await interfaceService.GetVLANsAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
WriteObject(result.Rows, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Imports an OPNSense firewall configuration.</para>
|
||||
/// <para type="description">The Import-OPNSenseConfig cmdlet imports an OPNSense firewall configuration from a file.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Import a configuration from a file</para>
|
||||
/// <code>Import-OPNSenseConfig -Path "C:\Backups\opnsense-config.xml"</code>
|
||||
/// <para>This example imports an OPNSense firewall configuration from a file.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Import, "OPNSenseConfig", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class ImportOPNSenseConfigCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The path to the configuration file.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if the file exists
|
||||
if (!File.Exists(Path))
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new FileNotFoundException($"The file '{Path}' does not exist."),
|
||||
"FileNotFound",
|
||||
ErrorCategory.ObjectNotFound,
|
||||
Path));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(Path, "Import configuration"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var configService = new ConfigService(ApiClient, Logger);
|
||||
|
||||
// Read the configuration file
|
||||
var configContent = File.ReadAllBytes(Path);
|
||||
|
||||
var task = Task.Run(async () => await configService.ImportConfigAsync(configContent));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Imported configuration from {Path}: {result.Status}");
|
||||
WriteWarning("The firewall is restarting. You may need to reconnect after it comes back online.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Installs a plugin on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Install-OPNSensePlugin cmdlet installs a plugin on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Install a plugin</para>
|
||||
/// <code>Install-OPNSensePlugin -Name "os-acme-client"</code>
|
||||
/// <para>This example installs the ACME client plugin on the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Install a plugin and wait for completion</para>
|
||||
/// <code>Install-OPNSensePlugin -Name "os-acme-client" -Wait</code>
|
||||
/// <para>This example installs the ACME client plugin on the OPNSense firewall and waits for the installation to complete.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Install, "OPNSensePlugin", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(void))]
|
||||
public class InstallOPNSensePluginCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the plugin to install.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Waits for the installation to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Wait { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timeout in seconds to wait for the installation to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 3600)]
|
||||
public int Timeout { get; set; } = 300;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interval in seconds between status checks.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 60)]
|
||||
public int Interval { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldProcess(Name, "Install plugin"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pluginService = new PluginService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await pluginService.InstallPluginAsync(Name));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Plugin installation initiated: {result.Status}");
|
||||
WriteObject($"Plugin installation initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for plugin installation to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for plugin installation to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
var statusTask = Task.Run(async () => await pluginService.GetPluginStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Plugin installation completed successfully");
|
||||
WriteObject("Plugin installation completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception($"Plugin installation failed: {statusResult.Log}"),
|
||||
"PluginInstallationFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
Name));
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Plugin installation status: {statusResult.Status}");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for plugin installation to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Net;
|
||||
using PSOPNSenseAPI.Utilities;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Performs network calculations using IPNetwork2.</para>
|
||||
/// <para type="description">The Invoke-OPNSenseNetworkCalculation cmdlet performs various network calculations using the IPNetwork2 library.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Get network information</para>
|
||||
/// <code>Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Info</code>
|
||||
/// <para>This example returns detailed information about the 192.168.1.0/24 network.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Divide a network into subnets</para>
|
||||
/// <code>Invoke-OPNSenseNetworkCalculation -Network "10.0.0.0/16" -Operation Subnet -PrefixLength 24</code>
|
||||
/// <para>This example divides the 10.0.0.0/16 network into /24 subnets.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Check if an IP address is within a network</para>
|
||||
/// <code>Invoke-OPNSenseNetworkCalculation -Network "192.168.1.0/24" -Operation Contains -IPAddress "192.168.1.100"</code>
|
||||
/// <para>This example checks if the IP address 192.168.1.100 is within the 192.168.1.0/24 network.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Invoke, "OPNSenseNetworkCalculation")]
|
||||
[OutputType(typeof(PSObject), typeof(bool), typeof(IPNetwork2[]))]
|
||||
public class InvokeOPNSenseNetworkCalculationCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The network in CIDR notation to perform calculations on.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Network { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The operation to perform.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateSet("Info", "Subnet", "SubnetByCount", "Contains", "Overlaps", "Supernet", "SupernetSummarize")]
|
||||
public string Operation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The prefix length for subnet operations.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 128)]
|
||||
public int? PrefixLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The number of subnets for SubnetByCount operations.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(2, int.MaxValue)]
|
||||
public int? SubnetCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address for Contains operations.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string IPAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The second network for Overlaps and Supernet operations.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] AdditionalNetworks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the network
|
||||
IPNetwork2 network = NetworkUtility.ParseCIDR(Network);
|
||||
|
||||
switch (Operation)
|
||||
{
|
||||
case "Info":
|
||||
WriteNetworkInfo(network);
|
||||
break;
|
||||
|
||||
case "Subnet":
|
||||
if (!PrefixLength.HasValue)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException("PrefixLength is required for Subnet operations."),
|
||||
"MissingPrefixLength",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteSubnets(network, PrefixLength.Value);
|
||||
break;
|
||||
|
||||
case "SubnetByCount":
|
||||
if (!SubnetCount.HasValue)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException("SubnetCount is required for SubnetByCount operations."),
|
||||
"MissingSubnetCount",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteSubnetsByCount(network, SubnetCount.Value);
|
||||
break;
|
||||
|
||||
case "Contains":
|
||||
if (string.IsNullOrEmpty(IPAddress))
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException("IPAddress is required for Contains operations."),
|
||||
"MissingIPAddress",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteContains(network, IPAddress);
|
||||
break;
|
||||
|
||||
case "Overlaps":
|
||||
if (AdditionalNetworks == null || AdditionalNetworks.Length == 0)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException("AdditionalNetworks is required for Overlaps operations."),
|
||||
"MissingAdditionalNetworks",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteOverlaps(network, AdditionalNetworks);
|
||||
break;
|
||||
|
||||
case "Supernet":
|
||||
if (AdditionalNetworks == null || AdditionalNetworks.Length == 0)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException("AdditionalNetworks is required for Supernet operations."),
|
||||
"MissingAdditionalNetworks",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteSupernet(network, AdditionalNetworks);
|
||||
break;
|
||||
|
||||
case "SupernetSummarize":
|
||||
if (AdditionalNetworks == null || AdditionalNetworks.Length == 0)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException("AdditionalNetworks is required for SupernetSummarize operations."),
|
||||
"MissingAdditionalNetworks",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
WriteSupernetSummarize(network, AdditionalNetworks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"NetworkCalculationError",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteNetworkInfo(IPNetwork2 network)
|
||||
{
|
||||
var info = new PSObject();
|
||||
info.Properties.Add(new PSNoteProperty("CIDR", network.ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("Network", network.Network.ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("Netmask", network.Netmask.ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("Broadcast", network.Broadcast.ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("FirstUsableHost", NetworkUtility.GetFirstUsableHost(network).ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("LastUsableHost", NetworkUtility.GetLastUsableHost(network).ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("UsableHostCount", NetworkUtility.GetUsableHostCount(network).ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("TotalAddressCount", network.Total.ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("AddressFamily", network.AddressFamily.ToString()));
|
||||
info.Properties.Add(new PSNoteProperty("PrefixLength", network.Cidr));
|
||||
info.Properties.Add(new PSNoteProperty("IsPrivate", NetworkUtility.IsPrivate(network.Network)));
|
||||
|
||||
WriteObject(info);
|
||||
}
|
||||
|
||||
private void WriteSubnets(IPNetwork2 network, int prefixLength)
|
||||
{
|
||||
if (prefixLength <= network.Cidr)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException($"Prefix length ({prefixLength}) must be greater than the network CIDR ({network.Cidr})."),
|
||||
"InvalidPrefixLength",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
return;
|
||||
}
|
||||
|
||||
var subnets = NetworkUtility.Subnet(network, prefixLength);
|
||||
WriteObject(subnets, true);
|
||||
}
|
||||
|
||||
private void WriteSubnetsByCount(IPNetwork2 network, int subnetCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
var subnets = NetworkUtility.SubnetByCount(network, subnetCount);
|
||||
WriteObject(subnets, true);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"InvalidSubnetCount",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteContains(IPNetwork2 network, string ipAddress)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if the input is an IP address or a network
|
||||
if (ipAddress.Contains("/"))
|
||||
{
|
||||
// It's a network
|
||||
IPNetwork2 otherNetwork = NetworkUtility.ParseCIDR(ipAddress);
|
||||
bool contains = NetworkUtility.Contains(network, otherNetwork);
|
||||
WriteObject(contains);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's an IP address
|
||||
System.Net.IPAddress ip = System.Net.IPAddress.Parse(ipAddress);
|
||||
bool contains = NetworkUtility.Contains(network, ip);
|
||||
WriteObject(contains);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"InvalidIPAddress",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteOverlaps(IPNetwork2 network, string[] additionalNetworks)
|
||||
{
|
||||
try
|
||||
{
|
||||
var results = new List<PSObject>();
|
||||
|
||||
foreach (var additionalNetwork in additionalNetworks)
|
||||
{
|
||||
IPNetwork2 otherNetwork = NetworkUtility.ParseCIDR(additionalNetwork);
|
||||
bool overlaps = NetworkUtility.Overlaps(network, otherNetwork);
|
||||
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("Network1", network.ToString()));
|
||||
result.Properties.Add(new PSNoteProperty("Network2", otherNetwork.ToString()));
|
||||
result.Properties.Add(new PSNoteProperty("Overlaps", overlaps));
|
||||
|
||||
results.Add(result);
|
||||
}
|
||||
|
||||
WriteObject(results, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"InvalidAdditionalNetwork",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteSupernet(IPNetwork2 network, string[] additionalNetworks)
|
||||
{
|
||||
try
|
||||
{
|
||||
var networks = new List<IPNetwork2> { network };
|
||||
|
||||
foreach (var additionalNetwork in additionalNetworks)
|
||||
{
|
||||
IPNetwork2 otherNetwork = NetworkUtility.ParseCIDR(additionalNetwork);
|
||||
networks.Add(otherNetwork);
|
||||
}
|
||||
|
||||
IPNetwork2 supernet = NetworkUtility.Supernet(networks.ToArray());
|
||||
WriteObject(supernet);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"SupernetError",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteSupernetSummarize(IPNetwork2 network, string[] additionalNetworks)
|
||||
{
|
||||
try
|
||||
{
|
||||
var networks = new List<IPNetwork2> { network };
|
||||
|
||||
foreach (var additionalNetwork in additionalNetworks)
|
||||
{
|
||||
IPNetwork2 otherNetwork = NetworkUtility.ParseCIDR(additionalNetwork);
|
||||
networks.Add(otherNetwork);
|
||||
}
|
||||
|
||||
List<IPNetwork2> summarizedNetworks = NetworkUtility.SupernetSummarize(networks);
|
||||
WriteObject(summarizedNetworks, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"SupernetSummarizeError",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new alias on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseAlias cmdlet creates a new alias on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new host alias</para>
|
||||
/// <code>New-OPNSenseAlias -Name "WebServers" -Type host -Content "192.168.1.10,192.168.1.11" -Description "Web Servers" -Apply</code>
|
||||
/// <para>This example creates a new host alias for web servers.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Create a new network alias</para>
|
||||
/// <code>New-OPNSenseAlias -Name "InternalNetworks" -Type network -Content "192.168.1.0/24,192.168.2.0/24" -Description "Internal Networks" -Apply</code>
|
||||
/// <para>This example creates a new network alias for internal networks.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Create a new port alias</para>
|
||||
/// <code>New-OPNSenseAlias -Name "WebPorts" -Type port -Content "80,443" -Protocol TCP -Description "Web Ports" -Apply</code>
|
||||
/// <para>This example creates a new port alias for web ports.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 4: Create a new URL alias</para>
|
||||
/// <code>New-OPNSenseAlias -Name "BlockList" -Type url -Content "https://example.com/blocklist.txt" -UpdateFrequency 1 -Description "Block List" -Apply</code>
|
||||
/// <para>This example creates a new URL alias for a block list that updates daily.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseAlias")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseAliasCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The type of the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateSet("host", "network", "port", "url", "urltable", "geoip", "networkgroup", "mac", "interface", "dynipv6host", "internal", "external")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The content of the alias. For host/network/port types, use comma-separated values. For URL types, specify the URL.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The protocol for port aliases (TCP, UDP, or TCP/UDP).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("TCP", "UDP", "TCP/UDP")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The update frequency for URL aliases (in days).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 365)]
|
||||
public int? UpdateFrequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable counters for the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableCounters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the alias is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var aliasService = new AliasService(ApiClient, Logger);
|
||||
|
||||
var alias = new AliasConfig
|
||||
{
|
||||
Name = Name,
|
||||
Type = Type.ToLower(),
|
||||
Content = Content,
|
||||
Description = Description,
|
||||
Enabled = Disabled.IsPresent ? "0" : "1",
|
||||
Counters = EnableCounters.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
// Set protocol for port aliases
|
||||
if (Type.Equals("port", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(Protocol))
|
||||
{
|
||||
alias.Protocol = Protocol.ToUpper();
|
||||
}
|
||||
|
||||
// Set update frequency for URL aliases
|
||||
if ((Type.Equals("url", StringComparison.OrdinalIgnoreCase) || Type.Equals("urltable", StringComparison.OrdinalIgnoreCase)) && UpdateFrequency.HasValue)
|
||||
{
|
||||
alias.UpdateFrequency = UpdateFrequency.Value.ToString();
|
||||
}
|
||||
|
||||
var createTask = Task.Run(async () => await aliasService.CreateAliasAsync(alias));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created alias with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await aliasService.ReconfigureAliasesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Alias changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new cron job on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseCronJob cmdlet creates a new cron job on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new cron job</para>
|
||||
/// <code>New-OPNSenseCronJob -Description "Daily backup" -Command "/usr/local/bin/backup.sh" -Minutes "0" -Hours "2" -Days "*" -Months "*" -Weekdays "*"</code>
|
||||
/// <para>This example creates a new cron job that runs a backup script at 2:00 AM every day.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Create a new cron job that runs weekly</para>
|
||||
/// <code>New-OPNSenseCronJob -Description "Weekly cleanup" -Command "/usr/local/bin/cleanup.sh" -Minutes "0" -Hours "3" -Days "*" -Months "*" -Weekdays "0"</code>
|
||||
/// <para>This example creates a new cron job that runs a cleanup script at 3:00 AM every Sunday.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseCronJob")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the cron job.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The command to run.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Command { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The minutes part of the cron schedule (0-59, *, */5, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Minutes { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The hours part of the cron schedule (0-23, *, */2, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Hours { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The days part of the cron schedule (1-31, *, */2, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Days { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The months part of the cron schedule (1-12, *, */2, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Months { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The weekdays part of the cron schedule (0-6, *, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Weekdays { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the cron job is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
var job = new CronJobConfig
|
||||
{
|
||||
Description = Description,
|
||||
Command = Command,
|
||||
Minutes = Minutes,
|
||||
Hours = Hours,
|
||||
Days = Days,
|
||||
Months = Months,
|
||||
Weekdays = Weekdays,
|
||||
Enabled = Enabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await cronService.CreateJobAsync(job));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created cron job with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new DHCP option on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseDHCPOption cmdlet creates a new DHCP option on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new DHCP option</para>
|
||||
/// <code>New-OPNSenseDHCPOption -Interface "lan" -Number 66 -Value "192.168.1.10" -Description "TFTP Server" -Apply</code>
|
||||
/// <para>This example creates a new DHCP option for the TFTP server.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseDHCPOption")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseDHCPOptionCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface name.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option number.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option value.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option type.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("string", "text", "boolean", "array")]
|
||||
public string Type { get; set; } = "string";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option description.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
var option = new DHCPOptionConfig
|
||||
{
|
||||
Number = Number,
|
||||
Value = Value,
|
||||
Type = Type,
|
||||
Description = Description
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await dhcpService.CreateOptionAsync(Interface, option));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created DHCP option with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new DHCP static mapping on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseDHCPStaticMapping cmdlet creates a new DHCP static mapping on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new static mapping</para>
|
||||
/// <code>New-OPNSenseDHCPStaticMapping -Interface "lan" -MacAddress "00:11:22:33:44:55" -IpAddress "192.168.1.100" -Hostname "printer" -Description "Office Printer"</code>
|
||||
/// <para>This example creates a new static mapping for a printer on the LAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseDHCPStaticMapping")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseDHCPStaticMappingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface to create the static mapping for.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The MAC address of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string MacAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The hostname of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Hostname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the static mapping is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
var mapping = new DHCPStaticMappingConfig
|
||||
{
|
||||
MacAddress = MacAddress,
|
||||
IpAddress = IpAddress,
|
||||
Hostname = Hostname,
|
||||
Description = Description,
|
||||
Enabled = Enabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await dhcpService.CreateStaticMappingAsync(Interface, mapping));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created static mapping with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new DNS forwarding host on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseDNSForwardingHost cmdlet creates a new DNS forwarding host on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new DNS forwarding host</para>
|
||||
/// <code>New-OPNSenseDNSForwardingHost -Domain "example.com" -Server "192.168.1.10" -Description "Internal DNS Server" -Apply</code>
|
||||
/// <para>This example creates a new DNS forwarding host for example.com that forwards to 192.168.1.10.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseDNSForwardingHost")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseDNSForwardingHostCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The domain to forward.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS server to forward to.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the forwarding host.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the forwarding host is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
var host = new DNSForwardingHostConfig
|
||||
{
|
||||
Domain = Domain,
|
||||
Server = Server,
|
||||
Description = Description,
|
||||
Enabled = Enabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await dnsService.CreateDNSForwardingHostAsync(host));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created DNS forwarding host with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new DNS override on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseDNSOverride cmdlet creates a new DNS override on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new DNS override</para>
|
||||
/// <code>New-OPNSenseDNSOverride -Hostname "server" -Domain "example.com" -IpAddress "192.168.1.10" -Description "Internal server"</code>
|
||||
/// <para>This example creates a new DNS override for server.example.com pointing to 192.168.1.10.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseDNSOverride")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseDNSOverrideCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The hostname part of the DNS override.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Hostname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The domain part of the DNS override.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address to resolve to.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the DNS override.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the DNS override is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
var dnsOverride = new DNSOverrideConfig
|
||||
{
|
||||
Hostname = Hostname,
|
||||
Domain = Domain,
|
||||
IpAddress = IpAddress,
|
||||
Description = Description,
|
||||
Enabled = Enabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await dnsService.CreateDNSOverrideAsync(dnsOverride));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created DNS override with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new firewall rule on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseFirewallRule cmdlet creates a new firewall rule on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a simple firewall rule</para>
|
||||
/// <code>New-OPNSenseFirewallRule -Description "Allow HTTP" -Protocol TCP -DestinationPort 80 -Action pass</code>
|
||||
/// <para>This example creates a new firewall rule that allows HTTP traffic.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Create a more specific firewall rule</para>
|
||||
/// <code>New-OPNSenseFirewallRule -Description "Allow HTTP from LAN" -Protocol TCP -SourceNet "192.168.1.0/24" -DestinationPort 80 -Action pass</code>
|
||||
/// <para>This example creates a new firewall rule that allows HTTP traffic from the LAN network.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseFirewallRule")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The protocol of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("any", "TCP", "UDP", "ICMP", "ESP", "AH", "GRE", "IGMP", "PIM", "OSPF")]
|
||||
public string Protocol { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source network of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SourceNet { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source port of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SourcePort { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination network of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string DestinationNet { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination port of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string DestinationPort { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The action of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("pass", "block", "reject")]
|
||||
public string Action { get; set; } = "pass";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The sequence of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Sequence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the firewall rule is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
var rule = new FirewallRuleCreate
|
||||
{
|
||||
Description = Description,
|
||||
Protocol = Protocol,
|
||||
SourceNet = SourceNet,
|
||||
SourcePort = SourcePort,
|
||||
DestinationNet = DestinationNet,
|
||||
DestinationPort = DestinationPort,
|
||||
Action = Action,
|
||||
Sequence = Sequence,
|
||||
Enabled = Enabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var task = Task.Run(async () => await firewallService.CreateRuleAsync(rule));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created firewall rule with UUID {result.Uuid}");
|
||||
WriteObject(result.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new gateway on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseGateway cmdlet creates a new gateway on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new gateway</para>
|
||||
/// <code>New-OPNSenseGateway -Name "WAN2" -Interface "opt1" -IpAddress "203.0.113.1" -Description "Secondary WAN" -Apply</code>
|
||||
/// <para>This example creates a new gateway for a secondary WAN interface.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Create a new default gateway</para>
|
||||
/// <code>New-OPNSenseGateway -Name "WAN_MAIN" -Interface "wan" -IpAddress "203.0.113.1" -Description "Main WAN" -Default -Apply</code>
|
||||
/// <para>This example creates a new default gateway for the WAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseGateway")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseGatewayCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interface of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The monitor IP of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string MonitorIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the gateway is the default gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Default { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the gateway is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The weight of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 30)]
|
||||
public int? Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP protocol of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("inet", "inet6")]
|
||||
public string IpProtocol { get; set; } = "inet";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to disable monitoring for the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter DisableMonitoring { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to force the gateway down.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter ForceDown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||
|
||||
var gateway = new GatewayConfig
|
||||
{
|
||||
Name = Name,
|
||||
Interface = Interface,
|
||||
IpAddress = IpAddress,
|
||||
MonitorIp = MonitorIp ?? IpAddress,
|
||||
Description = Description,
|
||||
IsDefault = Default.IsPresent ? "1" : "0",
|
||||
Disabled = Disabled.IsPresent ? "1" : "0",
|
||||
Weight = Weight?.ToString() ?? "1",
|
||||
IpProtocol = IpProtocol,
|
||||
MonitorDisable = DisableMonitoring.IsPresent ? "1" : "0",
|
||||
ForceDown = ForceDown.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await gatewayService.CreateGatewayAsync(gateway));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created gateway with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Models;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new port forwarding rule on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSensePortForwardingRule cmdlet creates a new port forwarding rule on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Create a new port forwarding rule</para>
|
||||
/// <code>New-OPNSensePortForwardingRule -Interface "WAN" -Protocol "tcp" -DestinationPort "80" -TargetIP "192.168.1.100" -TargetPort "80" -Description "Web Server"</code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSensePortForwardingRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Medium)]
|
||||
[OutputType(typeof(PortForwardingRule))]
|
||||
public class NewOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the rule is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interface for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true)]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The TCP/IP protocol (tcp, udp, tcp/udp).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("tcp", "udp", "tcp/udp")]
|
||||
public string Protocol { get; set; } = "tcp";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source address for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Source { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source port range for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SourcePort { get; set; } = "any";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination address for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Destination { get; set; } = "wanip";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination port range for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true)]
|
||||
public string DestinationPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The target IP address for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true)]
|
||||
public string TargetIP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The target port for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true)]
|
||||
public string TargetPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The NAT reflection mode (enable, disable, purenat).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("enable", "disable", "purenat")]
|
||||
public string NatReflection { get; set; } = "enable";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to create an associated filter rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter FilterRuleAssociation { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable logging for this rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Log { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
var rule = new PortForwardingRule
|
||||
{
|
||||
Enabled = Enabled,
|
||||
Description = Description,
|
||||
Interface = Interface,
|
||||
Protocol = Protocol,
|
||||
Source = Source,
|
||||
SourcePort = SourcePort,
|
||||
Destination = Destination,
|
||||
DestinationPort = DestinationPort,
|
||||
TargetIP = TargetIP,
|
||||
TargetPort = TargetPort,
|
||||
NatReflection = NatReflection,
|
||||
FilterRuleAssociation = FilterRuleAssociation,
|
||||
Log = Log
|
||||
};
|
||||
|
||||
if (Force || ShouldProcess($"OPNSense firewall", $"Create port forwarding rule from {Destination}:{DestinationPort} to {TargetIP}:{TargetPort}"))
|
||||
{
|
||||
var portForwardingService = new PortForwardingService(SessionState.ApiClient);
|
||||
var uuid = Task.Run(async () => await portForwardingService.CreatePortForwardingRuleAsync(rule)).GetAwaiter().GetResult();
|
||||
|
||||
if (!string.IsNullOrEmpty(uuid))
|
||||
{
|
||||
rule.Uuid = uuid;
|
||||
WriteObject(rule);
|
||||
WriteVerbose($"Port forwarding rule created successfully with UUID: {uuid}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new PSInvalidOperationException("Failed to create port forwarding rule."),
|
||||
"PortForwardingRuleCreationFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new route on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseRoute cmdlet creates a new route on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new route</para>
|
||||
/// <code>New-OPNSenseRoute -Network "192.168.100.0/24" -Gateway "WAN_GW" -Description "Remote Office" -Apply</code>
|
||||
/// <para>This example creates a new route to a remote office network.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseRoute")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseRouteCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The network of the route.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Network { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The gateway of the route.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Gateway { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the route.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the route is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var routeService = new RouteService(ApiClient, Logger);
|
||||
|
||||
var route = new RouteConfig
|
||||
{
|
||||
Network = Network,
|
||||
Gateway = Gateway,
|
||||
Description = Description,
|
||||
Disabled = Disabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
var createTask = Task.Run(async () => await routeService.CreateRouteAsync(route));
|
||||
var createResult = createTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created route with UUID {createResult.Uuid}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await routeService.ApplyRouteChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Route changes applied: {applyResult.Status}");
|
||||
}
|
||||
|
||||
WriteObject(createResult.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates VLANs for subnets on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseSubnetVLANs cmdlet divides a CIDR network into subnets and creates VLANs for each subnet on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create VLANs for subnets with sequential VLAN IDs</para>
|
||||
/// <code>New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "192.168.0.0/24" -SubnetMaskBits 27 -StartingVlanId 10 -VlanIdIncrement 1</code>
|
||||
/// <para>This example divides the 192.168.0.0/24 network into /27 subnets and creates VLANs with IDs 10, 11, 12, etc.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Create VLANs for subnets with VLAN IDs in multiples of 10</para>
|
||||
/// <code>New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "10.0.0.0/16" -SubnetMaskBits 24 -StartingVlanId 10 -VlanIdIncrement 10</code>
|
||||
/// <para>This example divides the 10.0.0.0/16 network into /24 subnets and creates VLANs with IDs 10, 20, 30, etc.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Create VLANs for subnets with DHCP enabled</para>
|
||||
/// <code>New-OPNSenseSubnetVLANs -ParentInterface "em0" -Network "172.16.0.0/20" -SubnetMaskBits 24 -StartingVlanId 100 -VlanIdIncrement 1 -EnableDHCP</code>
|
||||
/// <para>This example divides the 172.16.0.0/20 network into /24 subnets, creates VLANs with IDs 100, 101, 102, etc., and enables DHCP on each VLAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseSubnetVLANs", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(PSObject))]
|
||||
public class NewOPNSenseSubnetVLANsCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The parent interface for the VLANs.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string ParentInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The network in CIDR notation to divide into subnets.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Network { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The subnet mask bits for the subnets.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 2)]
|
||||
[ValidateRange(1, 32)]
|
||||
public int SubnetMaskBits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The starting VLAN ID.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 3)]
|
||||
[ValidateRange(1, 4094)]
|
||||
public int StartingVlanId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The increment for VLAN IDs.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 4)]
|
||||
[ValidateRange(1, 4094)]
|
||||
public int VlanIdIncrement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable DHCP on the VLAN interfaces.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableDHCP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The domain name for DHCP clients.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Domain { get; set; } = "local";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS servers for DHCP clients. If not specified, the gateway IP will be used.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] DnsServers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description prefix for the VLANs.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string DescriptionPrefix { get; set; } = "VLAN";
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the network CIDR
|
||||
var ipNetwork = IPNetwork2.Parse(Network);
|
||||
|
||||
// Validate subnet mask bits
|
||||
if (SubnetMaskBits <= ipNetwork.Cidr)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException($"Subnet mask bits ({SubnetMaskBits}) must be greater than the network CIDR ({ipNetwork.Cidr})."),
|
||||
"InvalidSubnetMaskBits",
|
||||
ErrorCategory.InvalidArgument,
|
||||
SubnetMaskBits));
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the number of subnets
|
||||
int numSubnets = (int)Math.Pow(2, SubnetMaskBits - ipNetwork.Cidr);
|
||||
|
||||
// Calculate the maximum VLAN ID
|
||||
int maxVlanId = StartingVlanId + (numSubnets - 1) * VlanIdIncrement;
|
||||
|
||||
// Validate the maximum VLAN ID
|
||||
if (maxVlanId > 4094)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new ArgumentException($"The maximum VLAN ID ({maxVlanId}) exceeds the maximum allowed value (4094)."),
|
||||
"InvalidVlanIdRange",
|
||||
ErrorCategory.InvalidArgument,
|
||||
maxVlanId));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get confirmation
|
||||
if (!Force.IsPresent && !ShouldProcess($"Create {numSubnets} VLANs for subnets of {Network} with VLAN IDs {StartingVlanId}-{maxVlanId}", "New-OPNSenseSubnetVLANs"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the interface service
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
// Verify the parent interface exists
|
||||
var getInterfaceTask = Task.Run(async () => await interfaceService.GetInterfaceDetailAsync(ParentInterface));
|
||||
getInterfaceTask.GetAwaiter().GetResult();
|
||||
|
||||
// Get existing VLANs
|
||||
var getVlansTask = Task.Run(async () => await interfaceService.GetVLANsAsync());
|
||||
var existingVlans = getVlansTask.GetAwaiter().GetResult().Rows;
|
||||
|
||||
// Create a list to store the created VLANs
|
||||
var createdVlans = new List<PSObject>();
|
||||
|
||||
// Get DHCP service if needed
|
||||
DHCPService dhcpService = null;
|
||||
if (EnableDHCP.IsPresent)
|
||||
{
|
||||
dhcpService = new DHCPService(ApiClient, Logger);
|
||||
}
|
||||
|
||||
// Divide the network into subnets
|
||||
var subnets = ipNetwork.Subnet((byte)SubnetMaskBits);
|
||||
int vlanId = StartingVlanId;
|
||||
int subnetIndex = 0;
|
||||
|
||||
foreach (var subnet in subnets)
|
||||
{
|
||||
// Calculate the gateway IP (first host address)
|
||||
var gatewayIp = GetFirstHostAddress(subnet);
|
||||
|
||||
// Calculate the DHCP range (second host address to last host address)
|
||||
var dhcpStart = GetSecondHostAddress(subnet);
|
||||
var dhcpEnd = GetLastHostAddress(subnet);
|
||||
|
||||
// Create a description for the VLAN
|
||||
string description = $"{DescriptionPrefix} {vlanId} - {subnet}";
|
||||
|
||||
// Check if the VLAN already exists
|
||||
var existingVlan = existingVlans.FirstOrDefault(v =>
|
||||
v.Interface == ParentInterface &&
|
||||
int.Parse(v.Tag) == vlanId);
|
||||
|
||||
if (existingVlan != null)
|
||||
{
|
||||
WriteVerbose($"VLAN {vlanId} already exists on interface {ParentInterface}");
|
||||
|
||||
// Add the existing VLAN to the list
|
||||
var vlanInfo = new PSObject();
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("VlanId", vlanId));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Subnet", subnet.ToString()));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Gateway", gatewayIp.ToString()));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Uuid", existingVlan.Uuid));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Status", "Existing"));
|
||||
|
||||
createdVlans.Add(vlanInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the VLAN
|
||||
var vlanConfig = new VLANConfig
|
||||
{
|
||||
Interface = ParentInterface,
|
||||
Tag = vlanId.ToString(),
|
||||
Priority = "0",
|
||||
Description = description
|
||||
};
|
||||
|
||||
var createVlanTask = Task.Run(async () => await interfaceService.CreateVLANAsync(vlanConfig));
|
||||
var createVlanResult = createVlanTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created VLAN {vlanId} on interface {ParentInterface} with UUID {createVlanResult.Uuid}");
|
||||
|
||||
// Configure the VLAN interface
|
||||
string vlanInterfaceName = $"{ParentInterface}.{vlanId}";
|
||||
|
||||
var interfaceConfig = new InterfaceConfig
|
||||
{
|
||||
Description = description,
|
||||
IpAddress = gatewayIp.ToString(),
|
||||
SubnetMask = SubnetMaskBits.ToString(),
|
||||
Enabled = "1"
|
||||
};
|
||||
|
||||
var updateInterfaceTask = Task.Run(async () => await interfaceService.UpdateInterfaceAsync(vlanInterfaceName, interfaceConfig));
|
||||
updateInterfaceTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Configured interface {vlanInterfaceName} with IP {gatewayIp}/{SubnetMaskBits}");
|
||||
|
||||
// If EnableDHCP is specified, configure DHCP for the interface
|
||||
if (EnableDHCP.IsPresent && dhcpService != null)
|
||||
{
|
||||
// Configure DHCP server for the interface
|
||||
var dhcpConfig = new DHCPServerConfig
|
||||
{
|
||||
Enabled = "1",
|
||||
RangeFrom = dhcpStart.ToString(),
|
||||
RangeTo = dhcpEnd.ToString(),
|
||||
DefaultLeaseTime = "7200",
|
||||
MaxLeaseTime = "86400",
|
||||
Domain = Domain,
|
||||
Gateway = gatewayIp.ToString(),
|
||||
DnsServers = DnsServers != null ? new List<string>(DnsServers) : new List<string> { gatewayIp.ToString() }
|
||||
};
|
||||
|
||||
var updateDhcpTask = Task.Run(async () => await dhcpService.UpdateServerAsync(vlanInterfaceName, dhcpConfig));
|
||||
updateDhcpTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Configured DHCP server for interface {vlanInterfaceName} with range {dhcpStart} - {dhcpEnd}");
|
||||
}
|
||||
|
||||
// Add the created VLAN to the list
|
||||
var vlanInfo = new PSObject();
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("VlanId", vlanId));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Subnet", subnet.ToString()));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Gateway", gatewayIp.ToString()));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Uuid", createVlanResult.Uuid));
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("Status", "Created"));
|
||||
if (EnableDHCP.IsPresent)
|
||||
{
|
||||
vlanInfo.Properties.Add(new PSNoteProperty("DHCPRange", $"{dhcpStart} - {dhcpEnd}"));
|
||||
}
|
||||
|
||||
createdVlans.Add(vlanInfo);
|
||||
}
|
||||
|
||||
// Increment the VLAN ID
|
||||
vlanId += VlanIdIncrement;
|
||||
subnetIndex++;
|
||||
}
|
||||
|
||||
// Apply DHCP changes if needed
|
||||
if (EnableDHCP.IsPresent && dhcpService != null)
|
||||
{
|
||||
var applyDhcpTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyDhcpResult = applyDhcpTask.GetAwaiter().GetResult();
|
||||
WriteVerbose($"Applied DHCP changes: {applyDhcpResult.Status}");
|
||||
}
|
||||
|
||||
// Create a result object
|
||||
var result = new PSObject();
|
||||
result.Properties.Add(new PSNoteProperty("ParentInterface", ParentInterface));
|
||||
result.Properties.Add(new PSNoteProperty("Network", Network));
|
||||
result.Properties.Add(new PSNoteProperty("SubnetMaskBits", SubnetMaskBits));
|
||||
result.Properties.Add(new PSNoteProperty("VLANs", createdVlans));
|
||||
|
||||
WriteObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first host address in a subnet
|
||||
/// </summary>
|
||||
/// <param name="subnet">The subnet</param>
|
||||
/// <returns>The first host address</returns>
|
||||
private static IPAddress GetFirstHostAddress(IPNetwork2 subnet)
|
||||
{
|
||||
byte[] addressBytes = subnet.Network.GetAddressBytes();
|
||||
|
||||
// If the subnet is too small (e.g., /31 or /32), return the network address
|
||||
if (subnet.Cidr >= 31)
|
||||
return subnet.Network;
|
||||
|
||||
// Increment the last byte of the network address by 1
|
||||
addressBytes[addressBytes.Length - 1]++;
|
||||
|
||||
return new IPAddress(addressBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the second host address in a subnet
|
||||
/// </summary>
|
||||
/// <param name="subnet">The subnet</param>
|
||||
/// <returns>The second host address</returns>
|
||||
private static IPAddress GetSecondHostAddress(IPNetwork2 subnet)
|
||||
{
|
||||
byte[] addressBytes = subnet.Network.GetAddressBytes();
|
||||
|
||||
// If the subnet is too small (e.g., /31 or /32), return the network address
|
||||
if (subnet.Cidr >= 31)
|
||||
return subnet.Network;
|
||||
|
||||
// If the subnet is /30, return the broadcast address - 1
|
||||
if (subnet.Cidr == 30)
|
||||
return subnet.Broadcast;
|
||||
|
||||
// Increment the last byte of the network address by 2
|
||||
addressBytes[addressBytes.Length - 1] += 2;
|
||||
|
||||
return new IPAddress(addressBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last host address in a subnet
|
||||
/// </summary>
|
||||
/// <param name="subnet">The subnet</param>
|
||||
/// <returns>The last host address</returns>
|
||||
private static IPAddress GetLastHostAddress(IPNetwork2 subnet)
|
||||
{
|
||||
byte[] broadcastBytes = subnet.Broadcast.GetAddressBytes();
|
||||
|
||||
// If the subnet is too small (e.g., /31 or /32), return the broadcast address
|
||||
if (subnet.Cidr >= 31)
|
||||
return subnet.Broadcast;
|
||||
|
||||
// Decrement the last byte of the broadcast address by 1
|
||||
broadcastBytes[broadcastBytes.Length - 1]--;
|
||||
|
||||
return new IPAddress(broadcastBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new user on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseUser cmdlet creates a new user on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new user</para>
|
||||
/// <code>New-OPNSenseUser -Username "john" -Password "P@ssw0rd" -FullName "John Doe" -Email "john@example.com" -Groups "admins"</code>
|
||||
/// <para>This example creates a new user with the specified properties.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseUser")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseUserCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The username of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The password of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The full name of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string FullName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The email of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The groups of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] Groups { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The authorizations of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] Authorizations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the user is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
|
||||
var user = new UserConfig
|
||||
{
|
||||
Username = Username,
|
||||
Password = Password,
|
||||
FullName = FullName,
|
||||
Email = Email,
|
||||
Disabled = Disabled.IsPresent ? "1" : "0",
|
||||
Groups = Groups != null ? new List<string>(Groups) : new List<string>(),
|
||||
Authorizations = Authorizations != null ? new List<string>(Authorizations) : new List<string>()
|
||||
};
|
||||
|
||||
var task = Task.Run(async () => await userService.CreateUserAsync(user));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created user with UUID {result.Uuid}");
|
||||
WriteObject(result.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Creates a new VLAN on an OPNSense firewall.</para>
|
||||
/// <para type="description">The New-OPNSenseVLAN cmdlet creates a new VLAN on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Create a new VLAN</para>
|
||||
/// <code>New-OPNSenseVLAN -Interface "em0" -Tag 10 -Description "Management VLAN"</code>
|
||||
/// <para>This example creates a new VLAN with tag 10 on interface em0.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.New, "OPNSenseVLAN")]
|
||||
[OutputType(typeof(string))]
|
||||
public class NewOPNSenseVLANCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The parent interface for the VLAN.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The VLAN tag (1-4094).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1)]
|
||||
[ValidateRange(1, 4094)]
|
||||
public int Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The priority of the VLAN (0-7).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(0, 7)]
|
||||
public int Priority { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the VLAN.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
var vlan = new VLANConfig
|
||||
{
|
||||
Interface = Interface,
|
||||
Tag = Tag.ToString(),
|
||||
Priority = Priority.ToString(),
|
||||
Description = Description
|
||||
};
|
||||
|
||||
var task = Task.Run(async () => await interfaceService.CreateVLANAsync(vlan));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Created VLAN with UUID {result.Uuid}");
|
||||
WriteObject(result.Uuid);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Models;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all OPNSense cmdlets
|
||||
/// </summary>
|
||||
public abstract class OPNSenseBaseCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the API client
|
||||
/// </summary>
|
||||
protected OPNSenseApiClient ApiClient => OPNSenseSession.Current;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the logger
|
||||
/// </summary>
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the cmdlet
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
base.BeginProcessing();
|
||||
Logger = new PowerShellLogger(this);
|
||||
|
||||
if (!OPNSenseSession.IsConnected)
|
||||
{
|
||||
ThrowTerminatingError(new ErrorRecord(
|
||||
new InvalidOperationException("Not connected to an OPNSense firewall. Use Connect-OPNSense first."),
|
||||
"NotConnected",
|
||||
ErrorCategory.ConnectionError,
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles exceptions
|
||||
/// </summary>
|
||||
/// <param name="ex">The exception to handle</param>
|
||||
protected void HandleException(Exception ex)
|
||||
{
|
||||
if (ex is OPNSenseApiException apiEx)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
apiEx,
|
||||
"OPNSenseApiError",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
ex,
|
||||
"OPNSenseError",
|
||||
ErrorCategory.NotSpecified,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for OPNSense cmdlets that use the new API client
|
||||
/// </summary>
|
||||
public abstract class OPNSenseCmdlet : PSCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the session state
|
||||
/// </summary>
|
||||
protected new OPNSenseSessionState SessionState => OPNSenseSessionState.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the cmdlet
|
||||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
base.BeginProcessing();
|
||||
|
||||
if (SessionState.ApiClient == null)
|
||||
{
|
||||
ThrowTerminatingError(new ErrorRecord(
|
||||
new InvalidOperationException("Not connected to an OPNSense firewall. Use Connect-OPNSense first."),
|
||||
"NotConnected",
|
||||
ErrorCategory.ConnectionError,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes an alias from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseAlias cmdlet removes an alias from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove an alias</para>
|
||||
/// <code>Remove-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Apply</code>
|
||||
/// <para>This example removes an alias by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove an alias with confirmation</para>
|
||||
/// <code>Remove-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm -Apply</code>
|
||||
/// <para>This example removes an alias by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Remove aliases by pipeline</para>
|
||||
/// <code>Get-OPNSenseAlias -Type host | Remove-OPNSenseAlias -Apply</code>
|
||||
/// <para>This example removes all host aliases.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseAlias", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseAliasCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the alias to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var aliasService = new AliasService(ApiClient, Logger);
|
||||
|
||||
// Get the alias details for the confirmation message
|
||||
var getTask = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
|
||||
var alias = getTask.GetAwaiter().GetResult().Alias;
|
||||
|
||||
string confirmMessage = $"Alias: {alias.Name} ({alias.Type})";
|
||||
if (!string.IsNullOrEmpty(alias.Description))
|
||||
{
|
||||
confirmMessage += $" - {alias.Description}";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await aliasService.DeleteAliasAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Alias {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await aliasService.ReconfigureAliasesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Alias changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a cron job from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseCronJob cmdlet removes a cron job from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a cron job</para>
|
||||
/// <code>Remove-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example removes a cron job by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a cron job with confirmation</para>
|
||||
/// <code>Remove-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm</code>
|
||||
/// <para>This example removes a cron job by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseCronJob", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the cron job to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
// Get the job details for the confirmation message
|
||||
var getTask = Task.Run(async () => await cronService.GetJobAsync(Uuid));
|
||||
var job = getTask.GetAwaiter().GetResult().Job;
|
||||
|
||||
string confirmMessage = $"Cron job: {job.Description}";
|
||||
if (!string.IsNullOrEmpty(job.Command))
|
||||
{
|
||||
confirmMessage += $" ({job.Command})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await cronService.DeleteJobAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron job {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a DHCP lease from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseDHCPLease cmdlet removes a DHCP lease from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a DHCP lease</para>
|
||||
/// <code>Remove-OPNSenseDHCPLease -MacAddress "00:11:22:33:44:55" -Apply</code>
|
||||
/// <para>This example removes a DHCP lease by its MAC address.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a DHCP lease with confirmation</para>
|
||||
/// <code>Remove-OPNSenseDHCPLease -MacAddress "00:11:22:33:44:55" -Confirm -Apply</code>
|
||||
/// <para>This example removes a DHCP lease by its MAC address after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseDHCPLease", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseDHCPLeaseCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The MAC address of the DHCP lease to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string MacAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
// Get the lease details for the confirmation message
|
||||
var getTask = Task.Run(async () => await dhcpService.GetLeaseByMacAsync(MacAddress));
|
||||
var lease = getTask.GetAwaiter().GetResult().Lease;
|
||||
|
||||
string confirmMessage = $"DHCP lease: {lease.MacAddress} -> {lease.IpAddress}";
|
||||
if (!string.IsNullOrEmpty(lease.Hostname))
|
||||
{
|
||||
confirmMessage += $" ({lease.Hostname})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await dhcpService.DeleteLeaseAsync(MacAddress));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP lease {MacAddress} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a DHCP option from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseDHCPOption cmdlet removes a DHCP option from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a DHCP option</para>
|
||||
/// <code>Remove-OPNSenseDHCPOption -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Apply</code>
|
||||
/// <para>This example removes a DHCP option by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a DHCP option with confirmation</para>
|
||||
/// <code>Remove-OPNSenseDHCPOption -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm -Apply</code>
|
||||
/// <para>This example removes a DHCP option by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseDHCPOption", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseDHCPOptionCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface name.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DHCP option to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
// Get the option details for the confirmation message
|
||||
var getTask = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
|
||||
var option = getTask.GetAwaiter().GetResult().Option;
|
||||
|
||||
string confirmMessage = $"DHCP option: {option.Number} = {option.Value}";
|
||||
if (!string.IsNullOrEmpty(option.Description))
|
||||
{
|
||||
confirmMessage += $" ({option.Description})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await dhcpService.DeleteOptionAsync(Interface, Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP option {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a DHCP static mapping from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseDHCPStaticMapping cmdlet removes a DHCP static mapping from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a static mapping</para>
|
||||
/// <code>Remove-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example removes a static mapping by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a static mapping with confirmation</para>
|
||||
/// <code>Remove-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm</code>
|
||||
/// <para>This example removes a static mapping by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseDHCPStaticMapping", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseDHCPStaticMappingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface of the static mapping to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the static mapping to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
// Get the mapping details for the confirmation message
|
||||
var getTask = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
|
||||
var mapping = getTask.GetAwaiter().GetResult().Mapping;
|
||||
|
||||
string confirmMessage = $"Static mapping: {mapping.MacAddress} -> {mapping.IpAddress}";
|
||||
if (!string.IsNullOrEmpty(mapping.Hostname))
|
||||
{
|
||||
confirmMessage += $" ({mapping.Hostname})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await dhcpService.DeleteStaticMappingAsync(Interface, Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Static mapping {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a DNS forwarding host from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseDNSForwardingHost cmdlet removes a DNS forwarding host from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a DNS forwarding host</para>
|
||||
/// <code>Remove-OPNSenseDNSForwardingHost -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Apply</code>
|
||||
/// <para>This example removes a DNS forwarding host by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a DNS forwarding host with confirmation</para>
|
||||
/// <code>Remove-OPNSenseDNSForwardingHost -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm -Apply</code>
|
||||
/// <para>This example removes a DNS forwarding host by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseDNSForwardingHost", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseDNSForwardingHostCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DNS forwarding host to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
// Get the host details for the confirmation message
|
||||
var getTask = Task.Run(async () => await dnsService.GetDNSForwardingHostAsync(Uuid));
|
||||
var host = getTask.GetAwaiter().GetResult().Host;
|
||||
|
||||
string confirmMessage = $"DNS forwarding host: {host.Domain} -> {host.Server}";
|
||||
if (!string.IsNullOrEmpty(host.Description))
|
||||
{
|
||||
confirmMessage += $" ({host.Description})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await dnsService.DeleteDNSForwardingHostAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS forwarding host {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a DNS override from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseDNSOverride cmdlet removes a DNS override from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a DNS override</para>
|
||||
/// <code>Remove-OPNSenseDNSOverride -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example removes a DNS override by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a DNS override with confirmation</para>
|
||||
/// <code>Remove-OPNSenseDNSOverride -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm</code>
|
||||
/// <para>This example removes a DNS override by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseDNSOverride", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseDNSOverrideCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DNS override to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
// Get the DNS override details for the confirmation message
|
||||
var getTask = Task.Run(async () => await dnsService.GetDNSOverrideAsync(Uuid));
|
||||
var dnsOverride = getTask.GetAwaiter().GetResult().Host;
|
||||
|
||||
string confirmMessage = $"DNS override {dnsOverride.Hostname}.{dnsOverride.Domain} -> {dnsOverride.IpAddress}";
|
||||
if (!string.IsNullOrEmpty(dnsOverride.Description))
|
||||
{
|
||||
confirmMessage += $" ({dnsOverride.Description})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await dnsService.DeleteDNSOverrideAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS override {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a firewall rule from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseFirewallRule cmdlet removes a firewall rule from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a firewall rule</para>
|
||||
/// <code>Remove-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example removes a firewall rule by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a firewall rule with confirmation</para>
|
||||
/// <code>Remove-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm</code>
|
||||
/// <para>This example removes a firewall rule by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseFirewallRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the firewall rule to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
// Get the rule details for the confirmation message
|
||||
var getTask = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
|
||||
var rule = getTask.GetAwaiter().GetResult().Rule;
|
||||
|
||||
string confirmMessage = $"Firewall rule: {rule.Description}";
|
||||
if (!string.IsNullOrEmpty(rule.Protocol) && rule.Protocol != "any")
|
||||
{
|
||||
confirmMessage += $" ({rule.Protocol})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await firewallService.DeleteRuleAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firewall rule {Uuid} removed: {deleteResult.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a gateway from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseGateway cmdlet removes a gateway from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a gateway</para>
|
||||
/// <code>Remove-OPNSenseGateway -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Apply</code>
|
||||
/// <para>This example removes a gateway by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a gateway with confirmation</para>
|
||||
/// <code>Remove-OPNSenseGateway -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm -Apply</code>
|
||||
/// <para>This example removes a gateway by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseGateway", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseGatewayCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the gateway to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||
|
||||
// Get the gateway details for the confirmation message
|
||||
var getTask = Task.Run(async () => await gatewayService.GetGatewayAsync(Uuid));
|
||||
var gateway = getTask.GetAwaiter().GetResult().Gateway;
|
||||
|
||||
string confirmMessage = $"Gateway: {gateway.Name} ({gateway.IpAddress})";
|
||||
if (!string.IsNullOrEmpty(gateway.Description))
|
||||
{
|
||||
confirmMessage += $" - {gateway.Description}";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await gatewayService.DeleteGatewayAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Gateway {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a port forwarding rule from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSensePortForwardingRule cmdlet removes a port forwarding rule from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Remove a port forwarding rule</para>
|
||||
/// <code>Remove-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"</code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSensePortForwardingRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
public class RemoveOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the port forwarding rule to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
var portForwardingService = new PortForwardingService(SessionState.ApiClient);
|
||||
|
||||
// Get the rule to display information in the confirmation message
|
||||
var rule = Task.Run(async () => await portForwardingService.GetPortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
|
||||
|
||||
if (rule == null)
|
||||
{
|
||||
WriteWarning($"Port forwarding rule with UUID '{Uuid}' not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
string confirmationMessage = $"Remove port forwarding rule";
|
||||
if (!string.IsNullOrEmpty(rule.Description))
|
||||
{
|
||||
confirmationMessage += $" '{rule.Description}'";
|
||||
}
|
||||
confirmationMessage += $" with UUID '{Uuid}'";
|
||||
|
||||
if (Force || ShouldProcess($"OPNSense firewall", confirmationMessage))
|
||||
{
|
||||
var success = Task.Run(async () => await portForwardingService.DeletePortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
|
||||
|
||||
if (success)
|
||||
{
|
||||
WriteVerbose($"Port forwarding rule with UUID '{Uuid}' removed successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new PSInvalidOperationException($"Failed to remove port forwarding rule with UUID '{Uuid}'."),
|
||||
"PortForwardingRuleRemovalFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
Uuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a route from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseRoute cmdlet removes a route from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a route</para>
|
||||
/// <code>Remove-OPNSenseRoute -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Apply</code>
|
||||
/// <para>This example removes a route by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a route with confirmation</para>
|
||||
/// <code>Remove-OPNSenseRoute -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm -Apply</code>
|
||||
/// <para>This example removes a route by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseRoute", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseRouteCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the route to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var routeService = new RouteService(ApiClient, Logger);
|
||||
|
||||
// Get the route details for the confirmation message
|
||||
var getTask = Task.Run(async () => await routeService.GetRouteAsync(Uuid));
|
||||
var route = getTask.GetAwaiter().GetResult().Route;
|
||||
|
||||
string confirmMessage = $"Route: {route.Network} via {route.Gateway}";
|
||||
if (!string.IsNullOrEmpty(route.Description))
|
||||
{
|
||||
confirmMessage += $" ({route.Description})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await routeService.DeleteRouteAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Route {Uuid} removed: {deleteResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await routeService.ApplyRouteChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Route changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a user from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseUser cmdlet removes a user from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a user</para>
|
||||
/// <code>Remove-OPNSenseUser -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example removes a user by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a user with confirmation</para>
|
||||
/// <code>Remove-OPNSenseUser -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm</code>
|
||||
/// <para>This example removes a user by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseUser", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseUserCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the user to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
|
||||
// Get the user details for the confirmation message
|
||||
var getTask = Task.Run(async () => await userService.GetUserAsync(Uuid));
|
||||
var user = getTask.GetAwaiter().GetResult().User;
|
||||
|
||||
string confirmMessage = $"User: {user.Username}";
|
||||
if (!string.IsNullOrEmpty(user.FullName))
|
||||
{
|
||||
confirmMessage += $" ({user.FullName})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await userService.DeleteUserAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"User {Uuid} removed: {deleteResult.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Removes a VLAN from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Remove-OPNSenseVLAN cmdlet removes a VLAN from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Remove a VLAN</para>
|
||||
/// <code>Remove-OPNSenseVLAN -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f"</code>
|
||||
/// <para>This example removes a VLAN by its UUID.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Remove a VLAN with confirmation</para>
|
||||
/// <code>Remove-OPNSenseVLAN -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Confirm</code>
|
||||
/// <para>This example removes a VLAN by its UUID after confirmation.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Remove, "OPNSenseVLAN", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RemoveOPNSenseVLANCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the VLAN to remove.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
// Get the VLAN details for the confirmation message
|
||||
var getTask = Task.Run(async () => await interfaceService.GetVLANAsync(Uuid));
|
||||
var vlan = getTask.GetAwaiter().GetResult().Vlan;
|
||||
|
||||
string confirmMessage = $"VLAN {vlan.Tag} on interface {vlan.Interface}";
|
||||
if (!string.IsNullOrEmpty(vlan.Description))
|
||||
{
|
||||
confirmMessage += $" ({vlan.Description})";
|
||||
}
|
||||
|
||||
if (!Force.IsPresent && !ShouldProcess(confirmMessage, "Remove"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var deleteTask = Task.Run(async () => await interfaceService.DeleteVLANAsync(Uuid));
|
||||
var deleteResult = deleteTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"VLAN {Uuid} removed: {deleteResult.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Logging;
|
||||
using PSOPNSenseAPI.Models;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Restarts an OPNSense firewall.</para>
|
||||
/// <para type="description">The Restart-OPNSenseFirewall cmdlet restarts an OPNSense firewall and optionally waits for it to come back online.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Restart a firewall</para>
|
||||
/// <code>Restart-OPNSenseFirewall</code>
|
||||
/// <para>This example restarts the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Restart a firewall and wait for it to come back online</para>
|
||||
/// <code>Restart-OPNSenseFirewall -Wait -Timeout 300</code>
|
||||
/// <para>This example restarts the OPNSense firewall and waits up to 5 minutes for it to come back online.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Restart, "OPNSenseFirewall", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RestartOPNSenseFirewallCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Waits for the firewall to come back online after restarting.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Wait { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timeout in seconds to wait for the firewall to come back online.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 3600)]
|
||||
public int Timeout { get; set; } = 180;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interval in seconds between connection attempts.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 60)]
|
||||
public int Interval { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Restart"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var systemService = new SystemService(ApiClient, Logger);
|
||||
|
||||
// Store connection information for reconnection
|
||||
string baseUrl = OPNSenseSession.BaseUrl;
|
||||
string apiKey = null;
|
||||
string apiSecret = null;
|
||||
bool skipCertificateCheck = false;
|
||||
|
||||
// Extract connection information from the current session
|
||||
if (ApiClient is OPNSenseApiClient client)
|
||||
{
|
||||
baseUrl = client.BaseUrl;
|
||||
apiKey = client.ApiKey;
|
||||
apiSecret = client.ApiSecret;
|
||||
skipCertificateCheck = client.SkipCertificateCheck;
|
||||
}
|
||||
|
||||
// If we couldn't get the credentials, we can't reconnect
|
||||
if (Wait.IsPresent && (string.IsNullOrEmpty(apiKey) || string.IsNullOrEmpty(apiSecret)))
|
||||
{
|
||||
WriteWarning("Could not retrieve API credentials from the current session. Will not attempt to reconnect after restart.");
|
||||
Wait = false;
|
||||
}
|
||||
|
||||
// Restart the firewall
|
||||
var task = Task.Run(async () => await systemService.RebootAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firewall restart initiated: {result.Status}");
|
||||
WriteObject("Firewall restart initiated. The firewall is now restarting.");
|
||||
|
||||
// Wait for the firewall to come back online if requested
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firewall to come back online (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firewall to come back online...");
|
||||
|
||||
// Disconnect the current session
|
||||
OPNSenseSession.Current?.Dispose();
|
||||
OPNSenseSession.Current = null;
|
||||
|
||||
// Wait a bit for the firewall to start rebooting
|
||||
Thread.Sleep(5000);
|
||||
|
||||
// Try to reconnect
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool reconnected = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteVerbose($"Attempting to reconnect to {baseUrl}...");
|
||||
|
||||
// Create a new logger
|
||||
var logger = new PowerShellLogger(this);
|
||||
|
||||
// Create a new API client
|
||||
var newClient = new OPNSenseApiClient(baseUrl, apiKey, apiSecret, skipCertificateCheck, logger);
|
||||
|
||||
// Try to get the system status
|
||||
var statusService = new SystemService(newClient, logger);
|
||||
var statusTask = Task.Run(async () => await statusService.GetStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
// If we get here, the firewall is back online
|
||||
WriteVerbose("Successfully reconnected to the firewall");
|
||||
WriteObject($"Firewall is back online. Uptime: {statusResult.Uptime}");
|
||||
|
||||
// Set the new session
|
||||
OPNSenseSession.Current = newClient;
|
||||
reconnected = true;
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteVerbose($"Reconnection attempt failed: {ex.Message}");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (!reconnected)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firewall to come back online after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Restarts an interface on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Restart-OPNSenseInterface cmdlet restarts an interface on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Restart an interface</para>
|
||||
/// <code>Restart-OPNSenseInterface -Name "lan"</code>
|
||||
/// <para>This example restarts the LAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Restart, "OPNSenseInterface", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RestartOPNSenseInterfaceCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the interface to restart.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess(Name, "Restart interface"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await interfaceService.RestartInterfaceAsync(Name));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Interface {Name} restarted: {result.Status}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Restores an OPNSense firewall configuration from a backup.</para>
|
||||
/// <para type="description">The Restore-OPNSenseConfig cmdlet restores an OPNSense firewall configuration from a backup.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Restore a configuration backup</para>
|
||||
/// <code>Restore-OPNSenseConfig -Filename "config-backup-20250414-1234.xml"</code>
|
||||
/// <para>This example restores an OPNSense firewall configuration from a backup file.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Restore, "OPNSenseConfig", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class RestoreOPNSenseConfigCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The filename of the backup to restore.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Filename { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess(Filename, "Restore configuration backup"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var configService = new ConfigService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await configService.RestoreConfigBackupAsync(Filename));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Restored configuration backup: {result.Status}");
|
||||
WriteWarning("The firewall is restarting. You may need to reconnect after it comes back online.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates an alias on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseAlias cmdlet updates an alias on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update an alias's content</para>
|
||||
/// <code>Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Content "192.168.1.10,192.168.1.11,192.168.1.12" -Apply</code>
|
||||
/// <para>This example updates the content of an alias.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update an alias's description</para>
|
||||
/// <code>Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Description "Updated description" -Apply</code>
|
||||
/// <para>This example updates the description of an alias.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 3: Disable an alias</para>
|
||||
/// <code>Set-OPNSenseAlias -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Disabled -Apply</code>
|
||||
/// <para>This example disables an alias.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseAlias")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseAliasCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the alias to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The content of the alias. For host/network/port types, use comma-separated values. For URL types, specify the URL.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The protocol for port aliases (TCP, UDP, or TCP/UDP).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("TCP", "UDP", "TCP/UDP")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The update frequency for URL aliases (in days).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 365)]
|
||||
public int? UpdateFrequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable counters for the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableCounters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to disable counters for the alias.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter DisableCounters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the alias is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the alias is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var aliasService = new AliasService(ApiClient, Logger);
|
||||
|
||||
// Get current alias
|
||||
var getTask = Task.Run(async () => await aliasService.GetAliasAsync(Uuid));
|
||||
var currentAlias = getTask.GetAwaiter().GetResult().Alias;
|
||||
|
||||
// Create updated alias
|
||||
var alias = new AliasConfig
|
||||
{
|
||||
Name = currentAlias.Name,
|
||||
Type = currentAlias.Type,
|
||||
Content = Content ?? currentAlias.Content,
|
||||
Description = Description ?? currentAlias.Description,
|
||||
Protocol = Protocol?.ToUpper() ?? currentAlias.Protocol,
|
||||
UpdateFrequency = UpdateFrequency?.ToString() ?? currentAlias.UpdateFrequency,
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
alias.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
alias.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
alias.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
alias.Enabled = currentAlias.Enabled;
|
||||
}
|
||||
|
||||
// Handle counters
|
||||
if (EnableCounters.IsPresent && DisableCounters.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -EnableCounters and -DisableCounters parameters were specified. Using -EnableCounters.");
|
||||
alias.Counters = "1";
|
||||
}
|
||||
else if (EnableCounters.IsPresent)
|
||||
{
|
||||
alias.Counters = "1";
|
||||
}
|
||||
else if (DisableCounters.IsPresent)
|
||||
{
|
||||
alias.Counters = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
alias.Counters = currentAlias.Counters;
|
||||
}
|
||||
|
||||
// Update alias
|
||||
var updateTask = Task.Run(async () => await aliasService.UpdateAliasAsync(Uuid, alias));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Alias {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await aliasService.ReconfigureAliasesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Alias changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a cron job on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseCronJob cmdlet updates a cron job on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a cron job's description</para>
|
||||
/// <code>Set-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Description "Updated backup job"</code>
|
||||
/// <para>This example updates the description of a cron job.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update a cron job's schedule</para>
|
||||
/// <code>Set-OPNSenseCronJob -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Hours "3" -Minutes "30"</code>
|
||||
/// <para>This example updates the schedule of a cron job to run at 3:30 AM.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseCronJob")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseCronJobCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the cron job to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the cron job.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The command to run.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Command { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The minutes part of the cron schedule (0-59, *, */5, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Minutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The hours part of the cron schedule (0-23, *, */2, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Hours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The days part of the cron schedule (1-31, *, */2, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Days { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The months part of the cron schedule (1-12, *, */2, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Months { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The weekdays part of the cron schedule (0-6, *, etc.).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Weekdays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the cron job is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the cron job is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cronService = new CronService(ApiClient, Logger);
|
||||
|
||||
// First, get the current job
|
||||
var getTask = Task.Run(async () => await cronService.GetJobAsync(Uuid));
|
||||
var currentJob = getTask.GetAwaiter().GetResult().Job;
|
||||
|
||||
// Create the updated job
|
||||
var job = new CronJobConfig
|
||||
{
|
||||
Description = Description ?? currentJob.Description,
|
||||
Command = Command ?? currentJob.Command,
|
||||
Minutes = Minutes ?? currentJob.Minutes,
|
||||
Hours = Hours ?? currentJob.Hours,
|
||||
Days = Days ?? currentJob.Days,
|
||||
Months = Months ?? currentJob.Months,
|
||||
Weekdays = Weekdays ?? currentJob.Weekdays
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
job.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
job.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
job.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
job.Enabled = currentJob.Enabled;
|
||||
}
|
||||
|
||||
// Update the job
|
||||
var updateTask = Task.Run(async () => await cronService.UpdateJobAsync(Uuid, job));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron job {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await cronService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Cron changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a DHCP option on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseDHCPOption cmdlet updates a DHCP option on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a DHCP option's value</para>
|
||||
/// <code>Set-OPNSenseDHCPOption -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Value "192.168.1.20" -Apply</code>
|
||||
/// <para>This example updates the value of a DHCP option.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseDHCPOption")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseDHCPOptionCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface name.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DHCP option to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option number.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option value.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option type.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("string", "text", "boolean", "array")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The option description.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
// Get current option
|
||||
var getTask = Task.Run(async () => await dhcpService.GetOptionAsync(Interface, Uuid));
|
||||
var currentOption = getTask.GetAwaiter().GetResult().Option;
|
||||
|
||||
// Create updated option
|
||||
var option = new DHCPOptionConfig
|
||||
{
|
||||
Number = Number ?? currentOption.Number,
|
||||
Value = Value ?? currentOption.Value,
|
||||
Type = Type ?? currentOption.Type,
|
||||
Description = Description ?? currentOption.Description
|
||||
};
|
||||
|
||||
// Update option
|
||||
var updateTask = Task.Run(async () => await dhcpService.UpdateOptionAsync(Interface, Uuid, option));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP option {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a DHCP server on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseDHCPServer cmdlet updates a DHCP server on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a DHCP server's range</para>
|
||||
/// <code>Set-OPNSenseDHCPServer -Interface "lan" -RangeFrom "192.168.1.100" -RangeTo "192.168.1.200"</code>
|
||||
/// <para>This example updates the DHCP range for the LAN interface.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update a DHCP server's DNS servers</para>
|
||||
/// <code>Set-OPNSenseDHCPServer -Interface "lan" -DnsServers "8.8.8.8","8.8.4.4" -Domain "example.com"</code>
|
||||
/// <para>This example updates the DNS servers and domain for the LAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseDHCPServer")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseDHCPServerCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface to update the DHCP server for.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The start of the DHCP range.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string RangeFrom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The end of the DHCP range.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string RangeTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The default lease time in seconds.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public int? DefaultLeaseTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The maximum lease time in seconds.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public int? MaxLeaseTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The domain name for DHCP clients.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS servers for DHCP clients.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] DnsServers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The gateway for DHCP clients.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Gateway { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the DHCP server is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the DHCP server is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
// First, get the current server configuration
|
||||
var getTask = Task.Run(async () => await dhcpService.GetServerAsync(Interface));
|
||||
var currentServer = getTask.GetAwaiter().GetResult().Server;
|
||||
|
||||
// Create the updated configuration
|
||||
var server = new DHCPServerConfig
|
||||
{
|
||||
RangeFrom = RangeFrom ?? currentServer.RangeFrom,
|
||||
RangeTo = RangeTo ?? currentServer.RangeTo,
|
||||
DefaultLeaseTime = DefaultLeaseTime?.ToString() ?? currentServer.DefaultLeaseTime,
|
||||
MaxLeaseTime = MaxLeaseTime?.ToString() ?? currentServer.MaxLeaseTime,
|
||||
Domain = Domain ?? currentServer.Domain,
|
||||
DnsServers = DnsServers != null ? new List<string>(DnsServers) : currentServer.DnsServers,
|
||||
Gateway = Gateway ?? currentServer.Gateway
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
server.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
server.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
server.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
server.Enabled = currentServer.Enabled;
|
||||
}
|
||||
|
||||
// Update the server
|
||||
var updateTask = Task.Run(async () => await dhcpService.UpdateServerAsync(Interface, server));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP server for interface {Interface} updated: {updateResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a DHCP static mapping on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseDHCPStaticMapping cmdlet updates a DHCP static mapping on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a static mapping's hostname</para>
|
||||
/// <code>Set-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Hostname "new-printer"</code>
|
||||
/// <para>This example updates the hostname of a static mapping.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update a static mapping's IP address</para>
|
||||
/// <code>Set-OPNSenseDHCPStaticMapping -Interface "lan" -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -IpAddress "192.168.1.101"</code>
|
||||
/// <para>This example updates the IP address of a static mapping.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseDHCPStaticMapping")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseDHCPStaticMappingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The interface of the static mapping to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the static mapping to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The MAC address of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string MacAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The hostname of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Hostname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the static mapping.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the static mapping is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the static mapping is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dhcpService = new DHCPService(ApiClient, Logger);
|
||||
|
||||
// First, get the current mapping
|
||||
var getTask = Task.Run(async () => await dhcpService.GetStaticMappingAsync(Interface, Uuid));
|
||||
var currentMapping = getTask.GetAwaiter().GetResult().Mapping;
|
||||
|
||||
// Create the updated mapping
|
||||
var mapping = new DHCPStaticMappingConfig
|
||||
{
|
||||
MacAddress = MacAddress ?? currentMapping.MacAddress,
|
||||
IpAddress = IpAddress ?? currentMapping.IpAddress,
|
||||
Hostname = Hostname ?? currentMapping.Hostname,
|
||||
Description = Description ?? currentMapping.Description
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
mapping.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
mapping.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
mapping.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
mapping.Enabled = currentMapping.Enabled;
|
||||
}
|
||||
|
||||
// Update the mapping
|
||||
var updateTask = Task.Run(async () => await dhcpService.UpdateStaticMappingAsync(Interface, Uuid, mapping));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Static mapping {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dhcpService.ApplyChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DHCP changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates the DNS forwarding configuration on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseDNSForwarding cmdlet updates the DNS forwarding configuration on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Enable DNS forwarding</para>
|
||||
/// <code>Set-OPNSenseDNSForwarding -Enabled -DnsServers "8.8.8.8","8.8.4.4" -Apply</code>
|
||||
/// <para>This example enables DNS forwarding and sets the DNS servers to Google's public DNS servers.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Disable DNS forwarding</para>
|
||||
/// <code>Set-OPNSenseDNSForwarding -Disabled -Apply</code>
|
||||
/// <para>This example disables DNS forwarding.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseDNSForwarding")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseDNSForwardingCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Whether DNS forwarding is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether DNS forwarding is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The type of DNS forwarding.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("forward", "redirect", "forward_domain")]
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS servers to forward to.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] DnsServers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
// Get current configuration
|
||||
var getTask = Task.Run(async () => await dnsService.GetDNSForwardingAsync());
|
||||
var currentConfig = getTask.GetAwaiter().GetResult().Forward;
|
||||
|
||||
// Create updated configuration
|
||||
var config = new DNSForwardingConfig
|
||||
{
|
||||
Type = Type ?? currentConfig.Type
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
config.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
config.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
config.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
config.Enabled = currentConfig.Enabled;
|
||||
}
|
||||
|
||||
// Handle DNS servers
|
||||
if (DnsServers != null && DnsServers.Length > 0)
|
||||
{
|
||||
config.DnsServers = new List<string>(DnsServers);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.DnsServers = currentConfig.DnsServers;
|
||||
}
|
||||
|
||||
// Update configuration
|
||||
var updateTask = Task.Run(async () => await dnsService.UpdateDNSForwardingAsync(config));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS forwarding configuration updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a DNS forwarding host on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseDNSForwardingHost cmdlet updates a DNS forwarding host on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a DNS forwarding host's server</para>
|
||||
/// <code>Set-OPNSenseDNSForwardingHost -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Server "192.168.1.20" -Apply</code>
|
||||
/// <para>This example updates the server of a DNS forwarding host.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Disable a DNS forwarding host</para>
|
||||
/// <code>Set-OPNSenseDNSForwardingHost -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Disabled -Apply</code>
|
||||
/// <para>This example disables a DNS forwarding host.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseDNSForwardingHost")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseDNSForwardingHostCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the DNS forwarding host to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The domain to forward.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS server to forward to.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the forwarding host.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the forwarding host is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the forwarding host is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
// Get current host
|
||||
var getTask = Task.Run(async () => await dnsService.GetDNSForwardingHostAsync(Uuid));
|
||||
var currentHost = getTask.GetAwaiter().GetResult().Host;
|
||||
|
||||
// Create updated host
|
||||
var host = new DNSForwardingHostConfig
|
||||
{
|
||||
Domain = Domain ?? currentHost.Domain,
|
||||
Server = Server ?? currentHost.Server,
|
||||
Description = Description ?? currentHost.Description
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
host.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
host.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
host.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
host.Enabled = currentHost.Enabled;
|
||||
}
|
||||
|
||||
// Update host
|
||||
var updateTask = Task.Run(async () => await dnsService.UpdateDNSForwardingHostAsync(Uuid, host));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS forwarding host {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates DNS server configuration on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseDNSServer cmdlet updates DNS server configuration on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Enable DNS forwarding</para>
|
||||
/// <code>Set-OPNSenseDNSServer -Forwarding -Forwarders "8.8.8.8","8.8.4.4"</code>
|
||||
/// <para>This example enables DNS forwarding and sets Google DNS servers as forwarders.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update DNS server port</para>
|
||||
/// <code>Set-OPNSenseDNSServer -Port 5353</code>
|
||||
/// <para>This example changes the DNS server port to 5353.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseDNSServer")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseDNSServerCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the DNS server is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS server port.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 65535)]
|
||||
public int? Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interfaces to listen on.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] Interfaces { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether DNS forwarding is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Forwarding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS forwarders to use.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] Forwarders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to register DHCP leases.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter RegisterDhcp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The domain to use for DHCP registrations.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string RegisterDhcpDomain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to register static DHCP leases.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter RegisterDhcpStatic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsService = new DNSService(ApiClient, Logger);
|
||||
|
||||
// First, get the current DNS configuration
|
||||
var getTask = Task.Run(async () => await dnsService.GetDNSConfigAsync());
|
||||
var currentConfig = getTask.GetAwaiter().GetResult().Unbound;
|
||||
|
||||
// Create the updated configuration
|
||||
var dnsConfig = new DNSConfig
|
||||
{
|
||||
Enabled = MyInvocation.BoundParameters.ContainsKey(nameof(Enabled)) ? (Enabled.IsPresent ? "1" : "0") : currentConfig.Enabled,
|
||||
Port = Port?.ToString() ?? currentConfig.Port,
|
||||
Interfaces = Interfaces != null ? new List<string>(Interfaces) : currentConfig.Interfaces,
|
||||
Forwarding = MyInvocation.BoundParameters.ContainsKey(nameof(Forwarding)) ? (Forwarding.IsPresent ? "1" : "0") : currentConfig.Forwarding,
|
||||
Forwarders = Forwarders != null ? new List<string>(Forwarders) : currentConfig.Forwarders,
|
||||
RegisterDhcp = MyInvocation.BoundParameters.ContainsKey(nameof(RegisterDhcp)) ? (RegisterDhcp.IsPresent ? "1" : "0") : currentConfig.RegisterDhcp,
|
||||
RegisterDhcpDomain = RegisterDhcpDomain ?? currentConfig.RegisterDhcpDomain,
|
||||
RegisterDhcpStatic = MyInvocation.BoundParameters.ContainsKey(nameof(RegisterDhcpStatic)) ? (RegisterDhcpStatic.IsPresent ? "1" : "0") : currentConfig.RegisterDhcpStatic,
|
||||
ActiveInterfaces = currentConfig.ActiveInterfaces
|
||||
};
|
||||
|
||||
// Update the DNS configuration
|
||||
var updateTask = Task.Run(async () => await dnsService.UpdateDNSConfigAsync(dnsConfig));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS server configuration updated: {updateResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await dnsService.ApplyDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a firewall rule on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseFirewallRule cmdlet updates a firewall rule on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a firewall rule description</para>
|
||||
/// <code>Set-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Description "Updated rule description"</code>
|
||||
/// <para>This example updates the description of a firewall rule.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update a firewall rule protocol and ports</para>
|
||||
/// <code>Set-OPNSenseFirewallRule -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Protocol TCP -DestinationPort 443</code>
|
||||
/// <para>This example updates the protocol and destination port of a firewall rule.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseFirewallRule")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseFirewallRuleCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the firewall rule to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The protocol of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("any", "TCP", "UDP", "ICMP", "ESP", "AH", "GRE", "IGMP", "PIM", "OSPF")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source network of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SourceNet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source port of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SourcePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination network of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string DestinationNet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination port of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string DestinationPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The action of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("pass", "block", "reject")]
|
||||
public string Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The sequence of the firewall rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Sequence { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the firewall rule is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the firewall rule is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var firewallService = new FirewallService(ApiClient, Logger);
|
||||
|
||||
// First, get the current rule
|
||||
var getTask = Task.Run(async () => await firewallService.GetRuleAsync(Uuid));
|
||||
var currentRule = getTask.GetAwaiter().GetResult().Rule;
|
||||
|
||||
// Create the updated rule
|
||||
var rule = new FirewallRuleCreate
|
||||
{
|
||||
Description = Description ?? currentRule.Description,
|
||||
Protocol = Protocol ?? currentRule.Protocol,
|
||||
SourceNet = SourceNet ?? currentRule.SourceNet,
|
||||
SourcePort = SourcePort ?? currentRule.SourcePort,
|
||||
DestinationNet = DestinationNet ?? currentRule.DestinationNet,
|
||||
DestinationPort = DestinationPort ?? currentRule.DestinationPort,
|
||||
Action = Action ?? currentRule.Action,
|
||||
Sequence = Sequence ?? currentRule.Sequence
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
rule.Enabled = "1";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
rule.Enabled = "1";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
rule.Enabled = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
rule.Enabled = currentRule.Enabled;
|
||||
}
|
||||
|
||||
// Update the rule
|
||||
var updateTask = Task.Run(async () => await firewallService.UpdateRuleAsync(Uuid, rule));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firewall rule {Uuid} updated: {updateResult.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a gateway on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseGateway cmdlet updates a gateway on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a gateway's monitor IP</para>
|
||||
/// <code>Set-OPNSenseGateway -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -MonitorIp "8.8.8.8" -Apply</code>
|
||||
/// <para>This example updates the monitor IP of a gateway.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Make a gateway the default gateway</para>
|
||||
/// <code>Set-OPNSenseGateway -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Default -Apply</code>
|
||||
/// <para>This example makes a gateway the default gateway.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseGateway")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseGatewayCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the gateway to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interface of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The monitor IP of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string MonitorIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the gateway is the default gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Default { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the gateway is not the default gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter NotDefault { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the gateway is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the gateway is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The weight of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 30)]
|
||||
public int? Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP protocol of the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("inet", "inet6")]
|
||||
public string IpProtocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable monitoring for the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableMonitoring { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to disable monitoring for the gateway.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter DisableMonitoring { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to force the gateway down.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter ForceDown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to not force the gateway down.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter NoForceDown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var gatewayService = new GatewayService(ApiClient, Logger);
|
||||
|
||||
// Get current gateway
|
||||
var getTask = Task.Run(async () => await gatewayService.GetGatewayAsync(Uuid));
|
||||
var currentGateway = getTask.GetAwaiter().GetResult().Gateway;
|
||||
|
||||
// Create updated gateway
|
||||
var gateway = new GatewayConfig
|
||||
{
|
||||
Name = Name ?? currentGateway.Name,
|
||||
Interface = Interface ?? currentGateway.Interface,
|
||||
IpAddress = IpAddress ?? currentGateway.IpAddress,
|
||||
MonitorIp = MonitorIp ?? currentGateway.MonitorIp,
|
||||
Description = Description ?? currentGateway.Description,
|
||||
Weight = Weight?.ToString() ?? currentGateway.Weight,
|
||||
IpProtocol = IpProtocol ?? currentGateway.IpProtocol
|
||||
};
|
||||
|
||||
// Handle default/not default
|
||||
if (Default.IsPresent && NotDefault.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Default and -NotDefault parameters were specified. Using -Default.");
|
||||
gateway.IsDefault = "1";
|
||||
}
|
||||
else if (Default.IsPresent)
|
||||
{
|
||||
gateway.IsDefault = "1";
|
||||
}
|
||||
else if (NotDefault.IsPresent)
|
||||
{
|
||||
gateway.IsDefault = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
gateway.IsDefault = currentGateway.IsDefault;
|
||||
}
|
||||
|
||||
// Handle enabled/disabled
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
gateway.Disabled = "0";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
gateway.Disabled = "0";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
gateway.Disabled = "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
gateway.Disabled = currentGateway.Disabled;
|
||||
}
|
||||
|
||||
// Handle monitoring
|
||||
if (EnableMonitoring.IsPresent && DisableMonitoring.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -EnableMonitoring and -DisableMonitoring parameters were specified. Using -EnableMonitoring.");
|
||||
gateway.MonitorDisable = "0";
|
||||
}
|
||||
else if (EnableMonitoring.IsPresent)
|
||||
{
|
||||
gateway.MonitorDisable = "0";
|
||||
}
|
||||
else if (DisableMonitoring.IsPresent)
|
||||
{
|
||||
gateway.MonitorDisable = "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
gateway.MonitorDisable = currentGateway.MonitorDisable;
|
||||
}
|
||||
|
||||
// Handle force down
|
||||
if (ForceDown.IsPresent && NoForceDown.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -ForceDown and -NoForceDown parameters were specified. Using -ForceDown.");
|
||||
gateway.ForceDown = "1";
|
||||
}
|
||||
else if (ForceDown.IsPresent)
|
||||
{
|
||||
gateway.ForceDown = "1";
|
||||
}
|
||||
else if (NoForceDown.IsPresent)
|
||||
{
|
||||
gateway.ForceDown = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
gateway.ForceDown = currentGateway.ForceDown;
|
||||
}
|
||||
|
||||
// Update gateway
|
||||
var updateTask = Task.Run(async () => await gatewayService.UpdateGatewayAsync(Uuid, gateway));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Gateway {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await gatewayService.ApplyGatewayChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Gateway changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates an interface on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseInterface cmdlet updates an interface on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update an interface description</para>
|
||||
/// <code>Set-OPNSenseInterface -Name "lan" -Description "Local Area Network"</code>
|
||||
/// <para>This example updates the description of the LAN interface.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update an interface IP address</para>
|
||||
/// <code>Set-OPNSenseInterface -Name "lan" -IpAddress "192.168.1.1" -SubnetMask "24"</code>
|
||||
/// <para>This example updates the IP address and subnet mask of the LAN interface.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseInterface")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseInterfaceCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the interface to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the interface.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The IP address of the interface.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string IpAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The subnet mask of the interface.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SubnetMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the interface is a DHCP client.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Dhcp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The gateway of the interface.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Gateway { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The MTU of the interface.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Mtu { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The speed/duplex of the interface.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Media { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the interface is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
// First, get the current interface configuration
|
||||
var getTask = Task.Run(async () => await interfaceService.GetInterfaceDetailAsync(Name));
|
||||
var currentInterface = getTask.GetAwaiter().GetResult().Interface;
|
||||
|
||||
// Create the updated configuration
|
||||
var interfaceConfig = new InterfaceConfig
|
||||
{
|
||||
Description = Description ?? currentInterface.Description,
|
||||
IpAddress = IpAddress ?? currentInterface.IpAddress,
|
||||
SubnetMask = SubnetMask ?? currentInterface.SubnetMask,
|
||||
Gateway = Gateway ?? currentInterface.Gateway,
|
||||
Enabled = Enabled.IsPresent ? "1" : "0"
|
||||
};
|
||||
|
||||
// Update the interface
|
||||
var updateTask = Task.Run(async () => await interfaceService.UpdateInterfaceAsync(Name, interfaceConfig));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Interface {Name} updated: {updateResult.Result}");
|
||||
|
||||
// Apply the changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var restartTask = Task.Run(async () => await interfaceService.RestartInterfaceAsync(Name));
|
||||
var restartResult = restartTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Interface {Name} restarted: {restartResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Models;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates an existing port forwarding rule on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSensePortForwardingRule cmdlet updates an existing port forwarding rule on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Update a port forwarding rule</para>
|
||||
/// <code>Set-OPNSensePortForwardingRule -Uuid "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6" -TargetIP "192.168.1.200" -Description "Updated Web Server"</code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSensePortForwardingRule", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Medium)]
|
||||
[OutputType(typeof(PortForwardingRule))]
|
||||
public class SetOPNSensePortForwardingRuleCmdlet : OPNSenseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the port forwarding rule to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the rule is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interface for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The TCP/IP protocol (tcp, udp, tcp/udp).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("tcp", "udp", "tcp/udp")]
|
||||
public string Protocol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source address for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The source port range for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string SourcePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination address for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Destination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The destination port range for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string DestinationPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The target IP address for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string TargetIP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The target port for the rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string TargetPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The NAT reflection mode (enable, disable, purenat).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateSet("enable", "disable", "purenat")]
|
||||
public string NatReflection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to create an associated filter rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter FilterRuleAssociation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable logging for this rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Log { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Returns the updated rule.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter PassThru { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
var portForwardingService = new PortForwardingService(SessionState.ApiClient);
|
||||
|
||||
// Get the existing rule
|
||||
var existingRule = Task.Run(async () => await portForwardingService.GetPortForwardingRuleAsync(Uuid)).GetAwaiter().GetResult();
|
||||
|
||||
if (existingRule == null)
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new PSArgumentException($"Port forwarding rule with UUID '{Uuid}' not found."),
|
||||
"PortForwardingRuleNotFound",
|
||||
ErrorCategory.ObjectNotFound,
|
||||
Uuid));
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the rule with the provided parameters
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Enabled)))
|
||||
existingRule.Enabled = Enabled;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Description)))
|
||||
existingRule.Description = Description;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Interface)))
|
||||
existingRule.Interface = Interface;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Protocol)))
|
||||
existingRule.Protocol = Protocol;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Source)))
|
||||
existingRule.Source = Source;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(SourcePort)))
|
||||
existingRule.SourcePort = SourcePort;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Destination)))
|
||||
existingRule.Destination = Destination;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(DestinationPort)))
|
||||
existingRule.DestinationPort = DestinationPort;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(TargetIP)))
|
||||
existingRule.TargetIP = TargetIP;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(TargetPort)))
|
||||
existingRule.TargetPort = TargetPort;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(NatReflection)))
|
||||
existingRule.NatReflection = NatReflection;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(FilterRuleAssociation)))
|
||||
existingRule.FilterRuleAssociation = FilterRuleAssociation;
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Log)))
|
||||
existingRule.Log = Log;
|
||||
|
||||
if (Force || ShouldProcess($"OPNSense firewall", $"Update port forwarding rule with UUID '{Uuid}'"))
|
||||
{
|
||||
var success = Task.Run(async () => await portForwardingService.UpdatePortForwardingRuleAsync(existingRule)).GetAwaiter().GetResult();
|
||||
|
||||
if (success)
|
||||
{
|
||||
WriteVerbose($"Port forwarding rule with UUID '{Uuid}' updated successfully.");
|
||||
|
||||
if (PassThru)
|
||||
{
|
||||
WriteObject(existingRule);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new PSInvalidOperationException($"Failed to update port forwarding rule with UUID '{Uuid}'."),
|
||||
"PortForwardingRuleUpdateFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
existingRule));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a route on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseRoute cmdlet updates a route on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a route's gateway</para>
|
||||
/// <code>Set-OPNSenseRoute -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Gateway "WAN2_GW" -Apply</code>
|
||||
/// <para>This example updates the gateway of a route.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Enable a disabled route</para>
|
||||
/// <code>Set-OPNSenseRoute -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Enabled -Apply</code>
|
||||
/// <para>This example enables a previously disabled route.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseRoute")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseRouteCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the route to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The network of the route.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Network { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The gateway of the route.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Gateway { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the route.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the route is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the route is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var routeService = new RouteService(ApiClient, Logger);
|
||||
|
||||
// Get current route
|
||||
var getTask = Task.Run(async () => await routeService.GetRouteAsync(Uuid));
|
||||
var currentRoute = getTask.GetAwaiter().GetResult().Route;
|
||||
|
||||
// Create updated route
|
||||
var route = new RouteConfig
|
||||
{
|
||||
Network = Network ?? currentRoute.Network,
|
||||
Gateway = Gateway ?? currentRoute.Gateway,
|
||||
Description = Description ?? currentRoute.Description
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
route.Disabled = "0";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
route.Disabled = "0";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
route.Disabled = "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
route.Disabled = currentRoute.Disabled;
|
||||
}
|
||||
|
||||
// Update route
|
||||
var updateTask = Task.Run(async () => await routeService.UpdateRouteAsync(Uuid, route));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Route {Uuid} updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await routeService.ApplyRouteChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Route changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates the system DNS configuration on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseSystemDNS cmdlet updates the system DNS configuration on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update system DNS servers</para>
|
||||
/// <code>Set-OPNSenseSystemDNS -DnsServers "8.8.8.8","8.8.4.4" -Apply</code>
|
||||
/// <para>This example updates the system DNS servers to Google's public DNS servers.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update system hostname and domain</para>
|
||||
/// <code>Set-OPNSenseSystemDNS -Hostname "firewall" -Domain "example.com" -Apply</code>
|
||||
/// <para>This example updates the system hostname and domain.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseSystemDNS")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseSystemDNSCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The hostname of the system.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Hostname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The domain of the system.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Domain { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The DNS servers of the system.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] DnsServers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to allow DNS server override by DHCP/PPP.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter AllowDnsOverride { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to disallow DNS server override by DHCP/PPP.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter DisallowDnsOverride { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to disable DNS rebinding protection.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter DisableDnsRebindProtection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to enable DNS rebinding protection.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter EnableDnsRebindProtection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timezone of the system.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Timezone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The time servers of the system.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string TimeServers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The language of the system.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Language { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether to apply the changes immediately.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Apply { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var systemDNSService = new SystemDNSService(ApiClient, Logger);
|
||||
|
||||
// Get current configuration
|
||||
var getTask = Task.Run(async () => await systemDNSService.GetSystemDNSAsync());
|
||||
var currentConfig = getTask.GetAwaiter().GetResult().System;
|
||||
|
||||
// Create updated configuration
|
||||
var config = new SystemDNSConfig
|
||||
{
|
||||
Hostname = Hostname ?? currentConfig.Hostname,
|
||||
Domain = Domain ?? currentConfig.Domain,
|
||||
Timezone = Timezone ?? currentConfig.Timezone,
|
||||
TimeServers = TimeServers ?? currentConfig.TimeServers,
|
||||
Language = Language ?? currentConfig.Language
|
||||
};
|
||||
|
||||
// Handle DNS servers
|
||||
if (DnsServers != null && DnsServers.Length > 0)
|
||||
{
|
||||
config.DnsServers = new List<string>(DnsServers);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.DnsServers = currentConfig.DnsServers;
|
||||
}
|
||||
|
||||
// Handle DNS override
|
||||
if (AllowDnsOverride.IsPresent && DisallowDnsOverride.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -AllowDnsOverride and -DisallowDnsOverride parameters were specified. Using -AllowDnsOverride.");
|
||||
config.DnsAllowOverride = "1";
|
||||
}
|
||||
else if (AllowDnsOverride.IsPresent)
|
||||
{
|
||||
config.DnsAllowOverride = "1";
|
||||
}
|
||||
else if (DisallowDnsOverride.IsPresent)
|
||||
{
|
||||
config.DnsAllowOverride = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
config.DnsAllowOverride = currentConfig.DnsAllowOverride;
|
||||
}
|
||||
|
||||
// Handle DNS rebind protection
|
||||
if (DisableDnsRebindProtection.IsPresent && EnableDnsRebindProtection.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -DisableDnsRebindProtection and -EnableDnsRebindProtection parameters were specified. Using -DisableDnsRebindProtection.");
|
||||
config.DnssecStripped = "1";
|
||||
}
|
||||
else if (DisableDnsRebindProtection.IsPresent)
|
||||
{
|
||||
config.DnssecStripped = "1";
|
||||
}
|
||||
else if (EnableDnsRebindProtection.IsPresent)
|
||||
{
|
||||
config.DnssecStripped = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
config.DnssecStripped = currentConfig.DnssecStripped;
|
||||
}
|
||||
|
||||
// Update configuration
|
||||
var updateTask = Task.Run(async () => await systemDNSService.UpdateSystemDNSAsync(config));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"System DNS configuration updated: {updateResult.Result}");
|
||||
|
||||
// Apply changes if requested
|
||||
if (Apply.IsPresent)
|
||||
{
|
||||
var applyTask = Task.Run(async () => await systemDNSService.ApplySystemDNSChangesAsync());
|
||||
var applyResult = applyTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"System DNS changes applied: {applyResult.Status}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a user on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseUser cmdlet updates a user on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a user's email</para>
|
||||
/// <code>Set-OPNSenseUser -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Email "newemail@example.com"</code>
|
||||
/// <para>This example updates the email of a user.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update a user's password</para>
|
||||
/// <code>Set-OPNSenseUser -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Password "NewP@ssw0rd"</code>
|
||||
/// <para>This example updates the password of a user.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseUser")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseUserCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the user to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The password of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The full name of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string FullName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The email of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The groups of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] Groups { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The authorizations of the user.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string[] Authorizations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the user is enabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Whether the user is disabled.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var userService = new UserService(ApiClient, Logger);
|
||||
|
||||
// First, get the current user
|
||||
var getTask = Task.Run(async () => await userService.GetUserAsync(Uuid));
|
||||
var currentUser = getTask.GetAwaiter().GetResult().User;
|
||||
|
||||
// Create the updated user
|
||||
var user = new UserConfig
|
||||
{
|
||||
Username = currentUser.Username,
|
||||
Password = Password ?? "",
|
||||
FullName = FullName ?? currentUser.FullName,
|
||||
Email = Email ?? currentUser.Email,
|
||||
Groups = Groups != null ? new List<string>(Groups) : currentUser.Groups,
|
||||
Authorizations = Authorizations != null ? new List<string>(Authorizations) : currentUser.Authorizations
|
||||
};
|
||||
|
||||
// Handle enabled/disabled state
|
||||
if (Enabled.IsPresent && Disabled.IsPresent)
|
||||
{
|
||||
WriteWarning("Both -Enabled and -Disabled parameters were specified. Using -Enabled.");
|
||||
user.Disabled = "0";
|
||||
}
|
||||
else if (Enabled.IsPresent)
|
||||
{
|
||||
user.Disabled = "0";
|
||||
}
|
||||
else if (Disabled.IsPresent)
|
||||
{
|
||||
user.Disabled = "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
user.Disabled = currentUser.Disabled;
|
||||
}
|
||||
|
||||
// Update the user
|
||||
var updateTask = Task.Run(async () => await userService.UpdateUserAsync(Uuid, user));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"User {Uuid} updated: {updateResult.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates a VLAN on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Set-OPNSenseVLAN cmdlet updates a VLAN on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update a VLAN description</para>
|
||||
/// <code>Set-OPNSenseVLAN -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Description "Updated VLAN Description"</code>
|
||||
/// <para>This example updates the description of a VLAN.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update a VLAN tag and priority</para>
|
||||
/// <code>Set-OPNSenseVLAN -Uuid "9e4ec4f0-9dd1-4fa3-8c1d-8a8e9d772b0f" -Tag 20 -Priority 3</code>
|
||||
/// <para>This example updates the tag and priority of a VLAN.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsCommon.Set, "OPNSenseVLAN")]
|
||||
[OutputType(typeof(void))]
|
||||
public class SetOPNSenseVLANCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The UUID of the VLAN to update.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The parent interface for the VLAN.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Interface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The VLAN tag (1-4094).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 4094)]
|
||||
public int? Tag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The priority of the VLAN (0-7).</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(0, 7)]
|
||||
public int? Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The description of the VLAN.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceService = new InterfaceService(ApiClient, Logger);
|
||||
|
||||
// First, get the current VLAN configuration
|
||||
var getTask = Task.Run(async () => await interfaceService.GetVLANAsync(Uuid));
|
||||
var currentVlan = getTask.GetAwaiter().GetResult().Vlan;
|
||||
|
||||
// Create the updated configuration
|
||||
var vlan = new VLANConfig
|
||||
{
|
||||
Interface = Interface ?? currentVlan.Interface,
|
||||
Tag = Tag?.ToString() ?? currentVlan.Tag,
|
||||
Priority = Priority?.ToString() ?? currentVlan.Priority,
|
||||
Description = Description ?? currentVlan.Description
|
||||
};
|
||||
|
||||
// Update the VLAN
|
||||
var updateTask = Task.Run(async () => await interfaceService.UpdateVLANAsync(Uuid, vlan));
|
||||
var updateResult = updateTask.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"VLAN {Uuid} updated: {updateResult.Result}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Uninstalls a plugin from an OPNSense firewall.</para>
|
||||
/// <para type="description">The Uninstall-OPNSensePlugin cmdlet uninstalls a plugin from an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Uninstall a plugin</para>
|
||||
/// <code>Uninstall-OPNSensePlugin -Name "os-acme-client"</code>
|
||||
/// <para>This example uninstalls the ACME client plugin from the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Uninstall a plugin and wait for completion</para>
|
||||
/// <code>Uninstall-OPNSensePlugin -Name "os-acme-client" -Wait</code>
|
||||
/// <para>This example uninstalls the ACME client plugin from the OPNSense firewall and waits for the uninstallation to complete.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsLifecycle.Uninstall, "OPNSensePlugin", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class UninstallOPNSensePluginCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">The name of the plugin to uninstall.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Waits for the uninstallation to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Wait { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timeout in seconds to wait for the uninstallation to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 3600)]
|
||||
public int Timeout { get; set; } = 300;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interval in seconds between status checks.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 60)]
|
||||
public int Interval { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess(Name, "Uninstall plugin"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pluginService = new PluginService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await pluginService.UninstallPluginAsync(Name));
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Plugin uninstallation initiated: {result.Status}");
|
||||
WriteObject($"Plugin uninstallation initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for plugin uninstallation to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for plugin uninstallation to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
var statusTask = Task.Run(async () => await pluginService.GetPluginStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Plugin uninstallation completed successfully");
|
||||
WriteObject("Plugin uninstallation completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception($"Plugin uninstallation failed: {statusResult.Log}"),
|
||||
"PluginUninstallationFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
Name));
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Plugin uninstallation status: {statusResult.Status}");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for plugin uninstallation to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Updates the firmware on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Update-OPNSenseFirmware cmdlet updates the firmware on an OPNSense firewall.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Update firmware</para>
|
||||
/// <code>Update-OPNSenseFirmware</code>
|
||||
/// <para>This example updates the firmware on the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Update firmware and wait for completion</para>
|
||||
/// <code>Update-OPNSenseFirmware -Wait</code>
|
||||
/// <para>This example updates the firmware on the OPNSense firewall and waits for the update to complete.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Update, "OPNSenseFirmware", SupportsShouldProcess = true)]
|
||||
[OutputType(typeof(void))]
|
||||
public class UpdateOPNSenseFirmwareCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Waits for the update to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Wait { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timeout in seconds to wait for the update to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 3600)]
|
||||
public int Timeout { get; set; } = 600;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interval in seconds between status checks.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 60)]
|
||||
public int Interval { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ShouldProcess("OPNSense firewall", "Update firmware"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await firmwareService.UpdateAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firmware update initiated: {result.Status}");
|
||||
WriteObject($"Firmware update initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firmware update to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firmware update to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Firmware update completed successfully");
|
||||
WriteObject("Firmware update completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception($"Firmware update failed: {statusResult.Log}"),
|
||||
"FirmwareUpdateFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware update status: {statusResult.Status}");
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firmware update to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PSOPNSenseAPI.Services;
|
||||
|
||||
namespace PSOPNSenseAPI.Cmdlets
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="synopsis">Upgrades the firmware on an OPNSense firewall.</para>
|
||||
/// <para type="description">The Upgrade-OPNSenseFirmware cmdlet upgrades the firmware on an OPNSense firewall to a new major version.</para>
|
||||
/// <example>
|
||||
/// <para>Example 1: Upgrade firmware</para>
|
||||
/// <code>Upgrade-OPNSenseFirmware</code>
|
||||
/// <para>This example upgrades the firmware on the OPNSense firewall.</para>
|
||||
/// </example>
|
||||
/// <example>
|
||||
/// <para>Example 2: Upgrade firmware and wait for completion</para>
|
||||
/// <code>Upgrade-OPNSenseFirmware -Wait</code>
|
||||
/// <para>This example upgrades the firmware on the OPNSense firewall and waits for the upgrade to complete.</para>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
[Cmdlet(VerbsData.Update, "OPNSenseFirmware", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.High)]
|
||||
[OutputType(typeof(void))]
|
||||
public class UpgradeOPNSenseFirmwareCmdlet : OPNSenseBaseCmdlet
|
||||
{
|
||||
/// <summary>
|
||||
/// <para type="description">Suppresses the confirmation prompt.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">Waits for the upgrade to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
public SwitchParameter Wait { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The timeout in seconds to wait for the upgrade to complete.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 3600)]
|
||||
public int Timeout { get; set; } = 1200;
|
||||
|
||||
/// <summary>
|
||||
/// <para type="description">The interval in seconds between status checks.</para>
|
||||
/// </summary>
|
||||
[Parameter(Mandatory = false)]
|
||||
[ValidateRange(1, 60)]
|
||||
public int Interval { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the cmdlet
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Force.IsPresent && !ShouldProcess("OPNSense firewall", "Upgrade firmware"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var firmwareService = new FirmwareService(ApiClient, Logger);
|
||||
|
||||
var task = Task.Run(async () => await firmwareService.UpgradeAsync());
|
||||
var result = task.GetAwaiter().GetResult();
|
||||
|
||||
WriteVerbose($"Firmware upgrade initiated: {result.Status}");
|
||||
WriteObject($"Firmware upgrade initiated: {result.Status}");
|
||||
|
||||
if (Wait.IsPresent)
|
||||
{
|
||||
WriteVerbose($"Waiting for firmware upgrade to complete (timeout: {Timeout} seconds, interval: {Interval} seconds)");
|
||||
WriteObject("Waiting for firmware upgrade to complete...");
|
||||
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool completed = false;
|
||||
|
||||
while (DateTime.Now - startTime < TimeSpan.FromSeconds(Timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var statusTask = Task.Run(async () => await firmwareService.GetStatusAsync());
|
||||
var statusResult = statusTask.GetAwaiter().GetResult();
|
||||
|
||||
if (statusResult.Status == "done")
|
||||
{
|
||||
WriteVerbose("Firmware upgrade completed successfully");
|
||||
WriteObject("Firmware upgrade completed successfully");
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
else if (statusResult.Status == "error")
|
||||
{
|
||||
WriteError(new ErrorRecord(
|
||||
new Exception($"Firmware upgrade failed: {statusResult.Log}"),
|
||||
"FirmwareUpgradeFailed",
|
||||
ErrorCategory.InvalidOperation,
|
||||
null));
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
WriteVerbose($"Firmware upgrade status: {statusResult.Status}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// The firewall might be rebooting, so we'll ignore errors during the wait
|
||||
WriteVerbose($"Error checking status (firewall might be rebooting): {ex.Message}");
|
||||
}
|
||||
|
||||
Thread.Sleep(Interval * 1000);
|
||||
}
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
WriteWarning($"Timed out waiting for firmware upgrade to complete after {Timeout} seconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user