Public/Network/Get-VergeNetworkRule.ps1
|
function Get-VergeNetworkRule { <# .SYNOPSIS Retrieves firewall rules from a VergeOS virtual network. .DESCRIPTION Get-VergeNetworkRule retrieves one or more firewall rules from a VergeOS network. You can filter rules by network, name, direction, action, or protocol. .PARAMETER Network The name or key of the network to retrieve rules from. This parameter is required. .PARAMETER NetworkObject A network object from Get-VergeNetwork. Accepts pipeline input. .PARAMETER Name The name of the rule to retrieve. Supports wildcards (* and ?). .PARAMETER Key The unique key (ID) of the rule to retrieve. .PARAMETER Direction Filter rules by direction: Incoming or Outgoing. .PARAMETER Action Filter rules by action: Accept, Drop, Reject, Translate, or Route. .PARAMETER Protocol Filter rules by protocol: TCP, UDP, TCPUDP, ICMP, or Any. .PARAMETER Enabled Filter by enabled status: $true for enabled rules, $false for disabled. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Get-VergeNetworkRule -Network "External" Retrieves all firewall rules from the External network. .EXAMPLE Get-VergeNetworkRule -Network "External" -Direction Incoming Retrieves all incoming rules from the External network. .EXAMPLE Get-VergeNetworkRule -Network "DMZ" -Action Accept -Protocol TCP Retrieves all TCP accept rules from the DMZ network. .EXAMPLE Get-VergeNetwork -Name "External" | Get-VergeNetworkRule Retrieves rules from a network using pipeline input. .EXAMPLE Get-VergeNetworkRule -Network "External" -Name "Web*" Retrieves rules with names starting with "Web" from the External network. .OUTPUTS PSCustomObject with PSTypeName 'Verge.NetworkRule' .NOTES Use New-VergeNetworkRule to create new rules. Use Invoke-VergeNetworkApply to apply rule changes. #> [CmdletBinding(DefaultParameterSetName = 'ByNetworkName')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByNetworkName')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByRuleKey')] [string]$Network, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByNetworkObject')] [PSTypeName('Verge.Network')] [PSCustomObject]$NetworkObject, [Parameter(ParameterSetName = 'ByNetworkName')] [Parameter(ParameterSetName = 'ByNetworkObject')] [SupportsWildcards()] [string]$Name, [Parameter(Mandatory, ParameterSetName = 'ByRuleKey')] [int]$Key, [Parameter(ParameterSetName = 'ByNetworkName')] [Parameter(ParameterSetName = 'ByNetworkObject')] [ValidateSet('Incoming', 'Outgoing')] [string]$Direction, [Parameter(ParameterSetName = 'ByNetworkName')] [Parameter(ParameterSetName = 'ByNetworkObject')] [ValidateSet('Accept', 'Drop', 'Reject', 'Translate', 'Route')] [string]$Action, [Parameter(ParameterSetName = 'ByNetworkName')] [Parameter(ParameterSetName = 'ByNetworkObject')] [ValidateSet('TCP', 'UDP', 'TCPUDP', 'ICMP', 'Any')] [string]$Protocol, [Parameter(ParameterSetName = 'ByNetworkName')] [Parameter(ParameterSetName = 'ByNetworkObject')] [bool]$Enabled, [Parameter()] [object]$Server ) begin { # Resolve connection if (-not $Server) { $Server = $script:DefaultConnection } if (-not $Server) { throw [System.InvalidOperationException]::new( 'Not connected to VergeOS. Use Connect-VergeOS to establish a connection.' ) } } process { # Resolve network $targetNetwork = $null if ($PSCmdlet.ParameterSetName -eq 'ByNetworkObject') { $targetNetwork = $NetworkObject } else { # Get network by name or key if ($Network -match '^\d+$') { $targetNetwork = Get-VergeNetwork -Key ([int]$Network) -Server $Server } else { $targetNetwork = Get-VergeNetwork -Name $Network -Server $Server } } if (-not $targetNetwork) { Write-Error -Message "Network '$Network' not found" -ErrorId 'NetworkNotFound' return } # Build query parameters $queryParams = @{} # Build filter string $filters = [System.Collections.Generic.List[string]]::new() # Always filter by network $filters.Add("vnet eq $($targetNetwork.Key)") # Filter by key if ($PSCmdlet.ParameterSetName -eq 'ByRuleKey') { $filters.Add("`$key eq $Key") } else { # Filter by name (with wildcard support) if ($Name) { if ($Name -match '[\*\?]') { $searchTerm = $Name -replace '[\*\?]', '' if ($searchTerm) { $filters.Add("name ct '$searchTerm'") } } else { $filters.Add("name eq '$Name'") } } # Filter by direction if ($Direction) { $directionMap = @{ 'Incoming' = 'incoming' 'Outgoing' = 'outgoing' } $filters.Add("direction eq '$($directionMap[$Direction])'") } # Filter by action if ($Action) { $actionMap = @{ 'Accept' = 'accept' 'Drop' = 'drop' 'Reject' = 'reject' 'Translate' = 'translate' 'Route' = 'route' } $filters.Add("action eq '$($actionMap[$Action])'") } # Filter by protocol if ($Protocol) { $protocolMap = @{ 'TCP' = 'tcp' 'UDP' = 'udp' 'TCPUDP' = 'tcpudp' 'ICMP' = 'icmp' 'Any' = 'any' } $filters.Add("protocol eq '$($protocolMap[$Protocol])'") } # Filter by enabled status if ($PSBoundParameters.ContainsKey('Enabled')) { $filters.Add("enabled eq $($Enabled.ToString().ToLower())") } } # Apply filters if ($filters.Count -gt 0) { $queryParams['filter'] = $filters -join ' and ' } # Select fields for comprehensive rule data $queryParams['fields'] = @( '$key' 'vnet' 'vnet#name as vnet_name' 'name' 'description' 'enabled' 'orderid' 'pin' 'direction' 'action' 'protocol' 'interface' 'source_ip' 'source_ports' 'destination_ip' 'destination_ports' 'target_ip' 'target_ports' 'ct_state' 'statistics' 'log' 'trace' 'throttle' 'drop_throttle' 'packets' 'bytes' 'system_rule' 'modified' ) -join ',' # Sort by orderid $queryParams['sort'] = 'orderid' try { Write-Verbose "Querying rules for network '$($targetNetwork.Name)'" $response = Invoke-VergeAPI -Method GET -Endpoint 'vnet_rules' -Query $queryParams -Connection $Server # Handle both single object and array responses $rules = if ($response -is [array]) { $response } else { @($response) } foreach ($rule in $rules) { # Skip null entries if (-not $rule -or -not $rule.name) { continue } # Map to user-friendly values $directionDisplay = switch ($rule.direction) { 'incoming' { 'Incoming' } 'outgoing' { 'Outgoing' } default { $rule.direction } } $actionDisplay = switch ($rule.action) { 'accept' { 'Accept' } 'drop' { 'Drop' } 'reject' { 'Reject' } 'translate' { 'Translate' } 'route' { 'Route' } default { $rule.action } } $protocolDisplay = switch ($rule.protocol) { 'tcp' { 'TCP' } 'udp' { 'UDP' } 'tcpudp' { 'TCP/UDP' } 'icmp' { 'ICMP' } 'any' { 'Any' } '89' { 'OSPF' } '2' { 'IGMP' } '47' { 'GRE' } '50' { 'ESP' } '51' { 'AH' } default { $rule.protocol } } # Create output object $output = [PSCustomObject]@{ PSTypeName = 'Verge.NetworkRule' Key = [int]$rule.'$key' NetworkKey = [int]$rule.vnet NetworkName = $rule.vnet_name Name = $rule.name Description = $rule.description Enabled = [bool]$rule.enabled Order = [int]$rule.orderid Pin = $rule.pin Direction = $directionDisplay DirectionRaw = $rule.direction Action = $actionDisplay ActionRaw = $rule.action Protocol = $protocolDisplay ProtocolRaw = $rule.protocol Interface = $rule.interface SourceIP = $rule.source_ip SourcePorts = $rule.source_ports DestinationIP = $rule.destination_ip DestinationPorts = $rule.destination_ports TargetIP = $rule.target_ip TargetPorts = $rule.target_ports ConnectionState = $rule.ct_state Statistics = [bool]$rule.statistics Log = [bool]$rule.log Trace = [bool]$rule.trace Throttle = $rule.throttle DropThrottle = [bool]$rule.drop_throttle Packets = $rule.packets Bytes = $rule.bytes SystemRule = [bool]$rule.system_rule Modified = if ($rule.modified) { [DateTimeOffset]::FromUnixTimeSeconds($rule.modified).LocalDateTime } else { $null } } # Add hidden properties for pipeline support $output | Add-Member -MemberType NoteProperty -Name '_Connection' -Value $Server -Force Write-Output $output } } catch { $PSCmdlet.ThrowTerminatingError($_) } } } |