diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml deleted file mode 100644 index 4f02240..0000000 --- a/.github/workflows/build-and-release.yml +++ /dev/null @@ -1,126 +0,0 @@ -name: Build and Release - -on: - push: - branches: [ main ] - paths-ignore: - - '**.md' - - 'docs/**' - - '.github/**' - - '!.github/workflows/build-and-release.yml' - pull_request: - branches: [ main ] - workflow_dispatch: - inputs: - release: - description: 'Create a release' - required: false - default: false - type: boolean - -jobs: - build: - runs-on: windows-latest - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Setup .NET - uses: actions/setup-dotnet@v3 - with: - dotnet-version: '6.0.x' - - - name: Setup PowerShell - uses: actions/setup-powershell@v1 - with: - powershell-version: '7.2' - - - name: Restore dependencies - run: dotnet restore src/PSOPNSenseAPI.sln - - - name: Run tests - run: pwsh -Command "./build/test.ps1 -Configuration Release" - - - name: Build and package - run: | - pwsh -Command "./build/build-release.ps1 -Clean -Package" - - - name: Upload build artifacts - uses: actions/upload-artifact@v3 - with: - name: PSOPNSenseAPI - path: output/PSOPNSenseAPI/ - - - name: Upload package artifacts - uses: actions/upload-artifact@v3 - with: - name: PSOPNSenseAPI-Package - path: packages/*.zip - - release: - needs: build - if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.event.inputs.release == 'true' - runs-on: windows-latest - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Setup PowerShell - uses: actions/setup-powershell@v1 - with: - powershell-version: '7.2' - - - name: Download build artifacts - uses: actions/download-artifact@v3 - with: - name: PSOPNSenseAPI - path: output/PSOPNSenseAPI/ - - - name: Download package artifacts - uses: actions/download-artifact@v3 - with: - name: PSOPNSenseAPI-Package - path: packages/ - - - name: Configure Git - run: | - git config --global user.name "GitHub Actions" - git config --global user.email "actions@github.com" - - - name: Create Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - $version = Get-Date -Format "yyyy.MM.dd.HHmm" - - # Update version in project file - $projectFile = "src/PSOPNSenseAPI/PSOPNSenseAPI.csproj" - $projectXml = [xml](Get-Content $projectFile) - $versionNode = $projectXml.Project.PropertyGroup.Version - $versionNode.InnerText = $version - $projectXml.Save($projectFile) - - # Update version in module manifest - $manifestFile = "PSOPNSenseAPI/PSOPNSenseAPI.psd1" - $manifestContent = Get-Content -Path $manifestFile -Raw - $manifestContent = $manifestContent -replace "ModuleVersion\s*=\s*['`"].*['`"]", "ModuleVersion = '$version'" - Set-Content -Path $manifestFile -Value $manifestContent - - # Commit changes - git add $projectFile - git add $manifestFile - git commit -m "Release version $version [skip ci]" - git push - - # Create release - $packagePath = Get-ChildItem -Path "packages/*.zip" | Select-Object -First 1 -ExpandProperty FullName - - gh release create "v$version" ` - --title "Release v$version" ` - --notes "Release version $version - $(Get-Date -Format 'yyyy-MM-dd')" ` - $packagePath - shell: pwsh diff --git a/.gitignore b/.gitignore index 4b82ccd..0fdfa7c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .vs/ bin/ obj/ +*.zip +output/*.zip diff --git a/output/PSOPNSenseAPI-v0.6.0-updated.zip b/output/PSOPNSenseAPI-v0.6.0-updated.zip deleted file mode 100644 index bf466c3..0000000 Binary files a/output/PSOPNSenseAPI-v0.6.0-updated.zip and /dev/null differ diff --git a/output/PSOPNSenseAPI-v0.6.0.zip b/output/PSOPNSenseAPI-v0.6.0.zip deleted file mode 100644 index b38cfe6..0000000 Binary files a/output/PSOPNSenseAPI-v0.6.0.zip and /dev/null differ diff --git a/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1 b/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1 index 4535f60..7deaec1 100644 --- a/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1 +++ b/output/PSOPNSenseAPI/PSOPNSenseAPI.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'PSOPNSenseAPI.psm1' - ModuleVersion = '2025.04.14.2253' + ModuleVersion = '2025.04.14.2306' GUID = '1f0e4b77-cc7c-4a1e-b45a-d7c51a3c562e' Author = 'PSOPNSenseAPI Contributors' CompanyName = 'PSOPNSenseAPI' diff --git a/output/PSOPNSenseAPI/lib/PSOPNSenseAPI.dll b/output/PSOPNSenseAPI/lib/PSOPNSenseAPI.dll index 46c59f8..d4f7805 100644 Binary files a/output/PSOPNSenseAPI/lib/PSOPNSenseAPI.dll and b/output/PSOPNSenseAPI/lib/PSOPNSenseAPI.dll differ diff --git a/src/PSOPNSenseAPI/PSOPNSenseAPI.csproj b/src/PSOPNSenseAPI/PSOPNSenseAPI.csproj index 51e99b2..7133ec5 100644 --- a/src/PSOPNSenseAPI/PSOPNSenseAPI.csproj +++ b/src/PSOPNSenseAPI/PSOPNSenseAPI.csproj @@ -4,7 +4,7 @@ netstandard2.0;net472 PSOPNSenseAPI PSOPNSenseAPI - 2025.04.14.2253 + 2025.04.14.2306 PSOPNSenseAPI Contributors PSOPNSenseAPI PowerShell module for interacting with the OPNSense API to configure firewalls diff --git a/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1 b/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1 index f82a537..d2a03a7 100644 --- a/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1 +++ b/src/PSOPNSenseAPI/PSOPNSenseAPI.psd1 @@ -1,9 +1,9 @@ @{ # Script module or binary module file associated with this manifest. - RootModule = 'PSOPNSenseAPI.dll' + RootModule = 'PSOPNSenseAPI.psm1' # Version number of this module. - ModuleVersion = '0.5.0' + ModuleVersion = '2025.04.14.2306' # Supported PSEditions CompatiblePSEditions = @('Desktop', 'Core') @@ -45,7 +45,7 @@ # RequiredModules = @() # Assemblies that must be loaded prior to importing this module - RequiredAssemblies = @('System.Net.Http', 'Newtonsoft.Json', 'System.Net.IPNetwork') + # RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @() diff --git a/src/PSOPNSenseAPI/Services/PortForwardingService.cs.bak b/src/PSOPNSenseAPI/Services/PortForwardingService.cs.bak deleted file mode 100644 index bb2b7d5..0000000 --- a/src/PSOPNSenseAPI/Services/PortForwardingService.cs.bak +++ /dev/null @@ -1,202 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PSOPNSenseAPI.Models; - -namespace PSOPNSenseAPI.Services -{ - /// - /// Service for managing port forwarding rules in OPNSense - /// - public class PortForwardingService : ServiceBase - { - /// - /// Initializes a new instance of the class - /// - /// The API client to use for requests - public PortForwardingService(ApiClient apiClient) : base(apiClient) - { - } - - /// - /// Gets all port forwarding rules - /// - /// A list of port forwarding rules - public async Task> GetPortForwardingRulesAsync() - { - var response = await ApiClient.GetAsync("/firewall/nat/getRule"); - var responseContent = await response.Content.ReadAsStringAsync(); - var jsonResponse = JObject.Parse(responseContent); - - if (jsonResponse["status"]?.ToString() != "ok") - { - throw new Exception($"Failed to get port forwarding rules: {jsonResponse["status_msg"]}"); - } - - var rules = new List(); - var rulesData = jsonResponse["rows"]; - - foreach (var rule in rulesData) - { - var portForwardingRule = new PortForwardingRule - { - Uuid = rule["uuid"]?.ToString(), - Enabled = rule["enabled"]?.ToString() == "1", - Description = rule["descr"]?.ToString(), - Interface = rule["interface"]?.ToString(), - Protocol = rule["protocol"]?.ToString(), - Source = rule["source"]?.ToString(), - SourcePort = rule["source_port"]?.ToString(), - Destination = rule["destination"]?.ToString(), - DestinationPort = rule["destination_port"]?.ToString(), - TargetIP = rule["target"]?.ToString(), - TargetPort = rule["target_port"]?.ToString(), - NatReflection = rule["natreflection"]?.ToString(), - FilterRuleAssociation = rule["associated-rule-id"]?.ToString() != "none", - Log = rule["log"]?.ToString() == "1" - }; - - rules.Add(portForwardingRule); - } - - return rules; - } - - /// - /// Gets a port forwarding rule by UUID - /// - /// The UUID of the rule to get - /// The port forwarding rule - public async Task GetPortForwardingRuleAsync(string uuid) - { - var rules = await GetPortForwardingRulesAsync(); - return rules.Find(r => r.Uuid == uuid); - } - - /// - /// Creates a new port forwarding rule - /// - /// The rule to create - /// The UUID of the created rule - public async Task CreatePortForwardingRuleAsync(PortForwardingRule rule) - { - var ruleData = new - { - rule = new - { - enabled = rule.Enabled ? "1" : "0", - descr = rule.Description, - interface = rule.Interface, - protocol = rule.Protocol, - source = rule.Source, - source_port = rule.SourcePort, - destination = rule.Destination, - destination_port = rule.DestinationPort, - target = rule.TargetIP, - target_port = rule.TargetPort, - natreflection = rule.NatReflection, - associated_rule_id = rule.FilterRuleAssociation ? "pass" : "none", - log = rule.Log ? "1" : "0" - } - }; - - var response = await ApiClient.PostAsync("/firewall/nat/addRule", ruleData); - var responseContent = await response.Content.ReadAsStringAsync(); - var jsonResponse = JObject.Parse(responseContent); - - if (jsonResponse["status"]?.ToString() != "ok") - { - throw new Exception($"Failed to create port forwarding rule: {jsonResponse["status_msg"]}"); - } - - // Apply changes - await ApplyChangesAsync(); - - return jsonResponse["uuid"]?.ToString(); - } - - /// - /// Updates an existing port forwarding rule - /// - /// The rule to update - /// True if successful - public async Task UpdatePortForwardingRuleAsync(PortForwardingRule rule) - { - if (string.IsNullOrEmpty(rule.Uuid)) - { - throw new ArgumentException("Rule UUID cannot be null or empty", nameof(rule)); - } - - var ruleData = new - { - rule = new - { - enabled = rule.Enabled ? "1" : "0", - descr = rule.Description, - interface = rule.Interface, - protocol = rule.Protocol, - source = rule.Source, - source_port = rule.SourcePort, - destination = rule.Destination, - destination_port = rule.DestinationPort, - target = rule.TargetIP, - target_port = rule.TargetPort, - natreflection = rule.NatReflection, - associated_rule_id = rule.FilterRuleAssociation ? "pass" : "none", - log = rule.Log ? "1" : "0" - } - }; - - var response = await ApiClient.PostAsync($"/firewall/nat/setRule/{rule.Uuid}", ruleData); - var responseContent = await response.Content.ReadAsStringAsync(); - var jsonResponse = JObject.Parse(responseContent); - - if (jsonResponse["status"]?.ToString() != "ok") - { - throw new Exception($"Failed to update port forwarding rule: {jsonResponse["status_msg"]}"); - } - - // Apply changes - await ApplyChangesAsync(); - - return true; - } - - /// - /// Deletes a port forwarding rule - /// - /// The UUID of the rule to delete - /// True if successful - public async Task DeletePortForwardingRuleAsync(string uuid) - { - var response = await ApiClient.PostAsync($"/firewall/nat/delRule/{uuid}", null); - var responseContent = await response.Content.ReadAsStringAsync(); - var jsonResponse = JObject.Parse(responseContent); - - if (jsonResponse["status"]?.ToString() != "ok") - { - throw new Exception($"Failed to delete port forwarding rule: {jsonResponse["status_msg"]}"); - } - - // Apply changes - await ApplyChangesAsync(); - - return true; - } - - /// - /// Applies the changes to the firewall - /// - /// True if successful - private async Task ApplyChangesAsync() - { - var response = await ApiClient.PostAsync("/firewall/nat/apply", null); - var responseContent = await response.Content.ReadAsStringAsync(); - var jsonResponse = JObject.Parse(responseContent); - - return jsonResponse["status"]?.ToString() == "ok"; - } - } -} diff --git a/temp_interface_service.cs b/temp_interface_service.cs deleted file mode 100644 index b448b00..0000000 --- a/temp_interface_service.cs +++ /dev/null @@ -1,289 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Newtonsoft.Json; -using PSOPNSenseAPI.Logging; -using PSOPNSenseAPI.Models; - -namespace PSOPNSenseAPI.Services -{ - public class InterfaceService - { - private readonly OPNSenseApiClient _apiClient; - private readonly ILogger _logger; - - public InterfaceService(OPNSenseApiClient apiClient, ILogger logger) - { - _apiClient = apiClient; - _logger = logger; - } - - public async Task GetInterfacesAsync() - { - _logger.Information("Getting interfaces"); - - var endpoint = "interfaces/overview/searchInterfaces"; - return await _apiClient.GetAsync(endpoint); - } - - public async Task GetInterfaceDetailAsync(string interfaceName) - { - _logger.Information($"Getting interface {interfaceName}"); - - var endpoint = $"interfaces/overview/getInterface/{interfaceName}"; - return await _apiClient.GetAsync(endpoint); - } - - public async Task GetInterfaceStatisticsAsync() - { - _logger.Information("Getting interface statistics"); - - var endpoint = "diagnostics/interface/getInterfaceStatistics"; - return await _apiClient.GetAsync(endpoint); - } - - public async Task UpdateInterfaceAsync(string interfaceName, InterfaceConfig interfaceConfig) - { - _logger.Information($"Updating interface {interfaceName}"); - - var endpoint = $"interfaces/overview/setInterface/{interfaceName}"; - var data = new { interface = interfaceConfig }; - return await _apiClient.PostAsync(endpoint, data); - } - - public async Task RestartInterfaceAsync(string interfaceName) - { - _logger.Information($"Restarting interface {interfaceName}"); - - var endpoint = $"interfaces/overview/reconfigure/{interfaceName}"; - return await _apiClient.PostAsync(endpoint); - } - - public async Task GetVLANsAsync() - { - _logger.Information("Getting VLANs"); - - var endpoint = "interfaces/vlan/searchItem"; - return await _apiClient.GetAsync(endpoint); - } - - public async Task GetVLANAsync(string uuid) - { - _logger.Information($"Getting VLAN with UUID {uuid}"); - - var endpoint = $"interfaces/vlan/getItem/{uuid}"; - return await _apiClient.GetAsync(endpoint); - } - - public async Task CreateVLANAsync(VLANConfig vlan) - { - _logger.Information("Creating VLAN"); - - var endpoint = "interfaces/vlan/addItem"; - var data = new { vlan = vlan }; - return await _apiClient.PostAsync(endpoint, data); - } - - public async Task UpdateVLANAsync(string uuid, VLANConfig vlan) - { - _logger.Information($"Updating VLAN with UUID {uuid}"); - - var endpoint = $"interfaces/vlan/setItem/{uuid}"; - var data = new { vlan = vlan }; - return await _apiClient.PostAsync(endpoint, data); - } - - public async Task DeleteVLANAsync(string uuid) - { - _logger.Information($"Deleting VLAN with UUID {uuid}"); - - var endpoint = $"interfaces/vlan/delItem/{uuid}"; - return await _apiClient.PostAsync(endpoint); - } - } - - public class InterfaceListResponse - { - [JsonProperty("rows")] - public List Interfaces { get; set; } - } - - public class InterfaceInfo - { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("description")] - public string Description { get; set; } - - [JsonProperty("ipaddr")] - public string IpAddress { get; set; } - - [JsonProperty("subnet")] - public string SubnetMask { get; set; } - - [JsonProperty("gateway")] - public string Gateway { get; set; } - - [JsonProperty("status")] - public string Status { get; set; } - } - - public class InterfaceDetailResponse - { - [JsonProperty("interface")] - public InterfaceDetail Interface { get; set; } - } - - public class InterfaceDetail - { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("description")] - public string Description { get; set; } - - [JsonProperty("ipaddr")] - public string IpAddress { get; set; } - - [JsonProperty("subnet")] - public string SubnetMask { get; set; } - - [JsonProperty("gateway")] - public string Gateway { get; set; } - - [JsonProperty("enable")] - public string Enabled { get; set; } - } - - public class InterfaceConfig - { - [JsonProperty("description")] - public string Description { get; set; } - - [JsonProperty("ipaddr")] - public string IpAddress { get; set; } - - [JsonProperty("subnet")] - public string SubnetMask { get; set; } - - [JsonProperty("gateway")] - public string Gateway { get; set; } - - [JsonProperty("enable")] - public string Enabled { get; set; } - } - - public class InterfaceUpdateResponse - { - [JsonProperty("result")] - public string Result { get; set; } - } - - public class InterfaceRestartResponse - { - [JsonProperty("status")] - public string Status { get; set; } - } - - public class InterfaceStatisticsResponse - { - [JsonProperty("statistics")] - public Dictionary Statistics { get; set; } - } - - public class InterfaceStatistics - { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("inpkts")] - public string InPackets { get; set; } - - [JsonProperty("outpkts")] - public string OutPackets { get; set; } - - [JsonProperty("inbytes")] - public string InBytes { get; set; } - - [JsonProperty("outbytes")] - public string OutBytes { get; set; } - } - - public class VLANListResponse - { - [JsonProperty("rows")] - public List Rows { get; set; } - } - - public class VLAN - { - [JsonProperty("uuid")] - public string Uuid { get; set; } - - [JsonProperty("if")] - public string Interface { get; set; } - - [JsonProperty("tag")] - public string Tag { get; set; } - - [JsonProperty("pcp")] - public string Priority { get; set; } - - [JsonProperty("descr")] - public string Description { get; set; } - } - - public class VLANResponse - { - [JsonProperty("vlan")] - public VLANDetail Vlan { get; set; } - } - - public class VLANDetail - { - [JsonProperty("if")] - public string Interface { get; set; } - - [JsonProperty("tag")] - public string Tag { get; set; } - - [JsonProperty("pcp")] - public string Priority { get; set; } - - [JsonProperty("descr")] - public string Description { get; set; } - } - - public class VLANConfig - { - [JsonProperty("if")] - public string Interface { get; set; } - - [JsonProperty("tag")] - public string Tag { get; set; } - - [JsonProperty("pcp")] - public string Priority { get; set; } - - [JsonProperty("descr")] - public string Description { get; set; } - } - - public class VLANCreateResponse - { - [JsonProperty("uuid")] - public string Uuid { get; set; } - } - - public class VLANUpdateResponse - { - [JsonProperty("result")] - public string Result { get; set; } - } - - public class VLANDeleteResponse - { - [JsonProperty("result")] - public string Result { get; set; } - } -}