commit 194e05d5cb1a00da89f71471dc178b1d89173ff2
Author: Tim Meusel <tim@bastelfreak.de>
Date:   Thu Jul 7 14:43:03 2022 +0200

    Add class for outgoing PXP connections

diff --git a/REFERENCE.md b/REFERENCE.md
index bf85d1a..b920ed6 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -53,6 +53,7 @@ and Manager Daemons (MGR).
 * [`nftables::rules::out::pop3`](#nftablesrulesoutpop3): allow outgoing pop3
 * [`nftables::rules::out::postgres`](#nftablesrulesoutpostgres): manage out postgres
 * [`nftables::rules::out::puppet`](#nftablesrulesoutpuppet): manage outgoing puppet
+* [`nftables::rules::out::pxp_agent`](#nftablesrulesoutpxp_agent): manage outgoing pxp-agent
 * [`nftables::rules::out::smtp`](#nftablesrulesoutsmtp): allow outgoing smtp
 * [`nftables::rules::out::smtp_client`](#nftablesrulesoutsmtp_client): allow outgoing smtp client
 * [`nftables::rules::out::ssh`](#nftablesrulesoutssh): manage out ssh
@@ -829,6 +830,35 @@ puppetserver port
 
 Default value: `8140`
 
+### <a name="nftablesrulesoutpxp_agent"></a>`nftables::rules::out::pxp_agent`
+
+manage outgoing pxp-agent
+
+* **See also**
+  * also
+    * take a look at nftables::rules::out::puppet, because the PXP agent also connects to a Puppetserver
+
+#### Parameters
+
+The following parameters are available in the `nftables::rules::out::pxp_agent` class:
+
+* [`broker`](#broker)
+* [`broker_port`](#broker_port)
+
+##### <a name="broker"></a>`broker`
+
+Data type: `Variant[Stdlib::IP::Address,Array[Stdlib::IP::Address,1]]`
+
+PXP broker IP(s)
+
+##### <a name="broker_port"></a>`broker_port`
+
+Data type: `Stdlib::Port`
+
+PXP broker port
+
+Default value: `8142`
+
 ### <a name="nftablesrulesoutsmtp"></a>`nftables::rules::out::smtp`
 
 allow outgoing smtp
diff --git a/manifests/rules/out/pxp_agent.pp b/manifests/rules/out/pxp_agent.pp
new file mode 100644
index 0000000..e7df77c
--- /dev/null
+++ b/manifests/rules/out/pxp_agent.pp
@@ -0,0 +1,26 @@
+# @summary manage outgoing pxp-agent
+#
+# @param broker PXP broker IP(s)
+# @param broker_port PXP broker port
+#
+# @see also take a look at nftables::rules::out::puppet, because the PXP agent also connects to a Puppetserver
+#
+class nftables::rules::out::pxp_agent (
+  Variant[Stdlib::IP::Address,Array[Stdlib::IP::Address,1]] $broker,
+  Stdlib::Port $broker_port = 8142,
+) {
+  Array($broker, true).each |$index,$ps| {
+    nftables::rule {
+      "default_out-pxpagent-${index}":
+    }
+    if $ps =~ Stdlib::IP::Address::V6 {
+      Nftables::Rule["default_out-pxpagent-${index}"] {
+        content => "ip6 daddr ${ps} tcp dport ${broker_port} accept",
+      }
+    } else {
+      Nftables::Rule["default_out-pxpagent-${index}"] {
+        content => "ip daddr ${ps} tcp dport ${broker_port} accept",
+      }
+    }
+  }
+}
diff --git a/spec/acceptance/all_rules_spec.rb b/spec/acceptance/all_rules_spec.rb
index 0156925..0cd1f1b 100644
--- a/spec/acceptance/all_rules_spec.rb
+++ b/spec/acceptance/all_rules_spec.rb
@@ -57,6 +57,9 @@ describe 'nftables class' do
       class{'nftables::rules::out::puppet':
         puppetserver => '127.0.0.1',
       }
+      class{'nftables::rules::out::pxp_agent':
+        broker => '127.0.0.1',
+      }
       include nftables::rules::out::all
       include nftables::rules::out::tor
       include nftables::rules::out::ospf3
diff --git a/spec/classes/rules/out/pxp_agent_spec.rb b/spec/classes/rules/out/pxp_agent_spec.rb
new file mode 100644
index 0000000..d44c455
--- /dev/null
+++ b/spec/classes/rules/out/pxp_agent_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'nftables::rules::out::pxp_agent' do
+  on_supported_os.each do |os, os_facts|
+    context "on #{os}" do
+      let(:facts) { os_facts }
+      let(:params) do
+        { broker: '1.2.3.4' }
+      end
+
+      context 'default options' do
+        it { is_expected.to compile.with_all_deps }
+        it { is_expected.to contain_nftables__rule('default_out-pxpagent-0').with_content('ip daddr 1.2.3.4 tcp dport 8142 accept') }
+      end
+
+      context 'with different port' do
+        let(:params) do
+          super().merge({ broker_port: 8141 })
+        end
+
+        it { is_expected.to compile.with_all_deps }
+        it { is_expected.to contain_nftables__rule('default_out-pxpagent-0').with_content('ip daddr 1.2.3.4 tcp dport 8141 accept') }
+      end
+
+      context 'with ipv6 address' do
+        let(:params) do
+          { broker: 'fe80::1' }
+        end
+
+        it { is_expected.to compile.with_all_deps }
+        it { is_expected.to contain_nftables__rule('default_out-pxpagent-0').with_content('ip6 daddr fe80::1 tcp dport 8142 accept') }
+      end
+
+      context 'with ipv6 & ipv4 address' do
+        let(:params) do
+          { broker: ['fe80::1', '1.2.3.4'] }
+        end
+
+        it { is_expected.to compile.with_all_deps }
+        it { is_expected.to contain_nftables__rule('default_out-pxpagent-0').with_content('ip6 daddr fe80::1 tcp dport 8142 accept') }
+        it { is_expected.to contain_nftables__rule('default_out-pxpagent-1').with_content('ip daddr 1.2.3.4 tcp dport 8142 accept') }
+        it { is_expected.to contain_concat__fragment('nftables-inet-filter-chain-default_out-rule-pxpagent-0') }
+        it { is_expected.to contain_concat__fragment('nftables-inet-filter-chain-default_out-rule-pxpagent-0_header') }
+        it { is_expected.to contain_concat__fragment('nftables-inet-filter-chain-default_out-rule-pxpagent-1') }
+        it { is_expected.to contain_concat__fragment('nftables-inet-filter-chain-default_out-rule-pxpagent-1_header') }
+      end
+    end
+  end
+end
