Showing preview only (2,942K chars total). Download the full file or copy to clipboard to get everything.
Repository: pfsensible/core
Branch: master
Commit: 62b56a13829c
Files: 211
Total size: 2.8 MB
Directory structure:
gitextract_2409rtmf/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── main.yml
├── .gitignore
├── CHANGELOG.rst
├── GENERATING_MODULES.md
├── LICENSE
├── README.md
├── changelogs/
│ ├── .plugin-cache.yaml
│ ├── 134_openvpn_digest.yml
│ ├── changelog.yaml
│ ├── config.yaml
│ └── fragments/
│ ├── 129_sshguard_whitelist.yaml
│ ├── 217_pfsense_setup_webguicert.yml
│ ├── 219_parse_address_ipv6.yml
│ ├── 223_fix_openvpn_alias_expansion.yml
│ ├── 224_add_dco_for_plus_versions.yml
│ ├── 226_dns_resolver.yaml
│ ├── 228_interface_diff.yml
│ ├── 238_pfsense_openvpn_server.yml
│ ├── 239_sync_config.yml
│ ├── 242_gateway_loss.yml
│ ├── 243_openvpn_client.yml
│ ├── 245_arg_route.yaml
│ ├── 248_class_level_imports.yaml
│ ├── 251_setup_hardware.yaml
│ ├── rule_pass_before_deny_ordering.yml
│ └── rule_protocol_any_with_ports.yml
├── examples/
│ ├── ipsec/
│ │ ├── README.md
│ │ ├── filter_plugins/
│ │ │ └── pfsense.py
│ │ ├── hosts
│ │ ├── ipsecs.yaml
│ │ ├── more.ipsecs.yaml
│ │ └── setup_ipsec.yml
│ ├── lookup/
│ │ ├── README.md
│ │ ├── hosts
│ │ ├── pfsense_definitions.yaml
│ │ └── setup_all_rules.yml
│ ├── pfsense.yml
│ ├── pfsense_setup.yml
│ └── roles/
│ ├── pfsense/
│ │ └── tasks/
│ │ ├── fail2ban.yml
│ │ └── main.yml
│ └── pfsense_setup/
│ ├── tasks/
│ │ ├── main.yml
│ │ └── setup_user.yml
│ └── templates/
│ └── nslcd.conf.j2
├── galaxy.yml
├── meta/
│ └── runtime.yml
├── misc/
│ ├── .coveragerc
│ ├── ansible2local
│ ├── local2ansible
│ ├── mkpfcollection
│ ├── mkpfsensible
│ ├── pfsense_module.py.j2
│ ├── pfsensible-generate-module
│ ├── pytest
│ ├── run_ansible_sanity_tests
│ └── setup_units_tests
├── plugins/
│ ├── lookup/
│ │ └── pfsense.py
│ ├── module_utils/
│ │ ├── __init__.py
│ │ ├── alias.py
│ │ ├── arg_route.py
│ │ ├── arg_validate.py
│ │ ├── default_gateway.py
│ │ ├── dhcp_server.py
│ │ ├── gateway.py
│ │ ├── haproxy_backend.py
│ │ ├── haproxy_backend_server.py
│ │ ├── interface.py
│ │ ├── interface_group.py
│ │ ├── ipsec.py
│ │ ├── ipsec_p2.py
│ │ ├── ipsec_proposal.py
│ │ ├── module_base.py
│ │ ├── module_config_base.py
│ │ ├── nat_outbound.py
│ │ ├── nat_port_forward.py
│ │ ├── openvpn_client.py
│ │ ├── openvpn_override.py
│ │ ├── openvpn_server.py
│ │ ├── pfsense.py
│ │ ├── route.py
│ │ ├── rule.py
│ │ ├── rule_separator.py
│ │ └── vlan.py
│ └── modules/
│ ├── pfsense_aggregate.py
│ ├── pfsense_alias.py
│ ├── pfsense_authserver_ldap.py
│ ├── pfsense_authserver_radius.py
│ ├── pfsense_ca.py
│ ├── pfsense_cert.py
│ ├── pfsense_default_gateway.py
│ ├── pfsense_dhcp_server.py
│ ├── pfsense_dhcp_static.py
│ ├── pfsense_dns_resolver.py
│ ├── pfsense_gateway.py
│ ├── pfsense_gateway_group.py
│ ├── pfsense_group.py
│ ├── pfsense_haproxy_backend.py
│ ├── pfsense_haproxy_backend_server.py
│ ├── pfsense_interface.py
│ ├── pfsense_interface_group.py
│ ├── pfsense_ipsec.py
│ ├── pfsense_ipsec_aggregate.py
│ ├── pfsense_ipsec_p2.py
│ ├── pfsense_ipsec_proposal.py
│ ├── pfsense_log_settings.py
│ ├── pfsense_nat_outbound.py
│ ├── pfsense_nat_port_forward.py
│ ├── pfsense_openvpn_client.py
│ ├── pfsense_openvpn_override.py
│ ├── pfsense_openvpn_server.py
│ ├── pfsense_phpshell.py
│ ├── pfsense_rewrite_config.py
│ ├── pfsense_route.py
│ ├── pfsense_rule.py
│ ├── pfsense_rule_separator.py
│ ├── pfsense_setup.py
│ ├── pfsense_shellcmd.py
│ ├── pfsense_user.py
│ └── pfsense_vlan.py
├── setup.cfg
└── tests/
├── plays/
│ ├── README.md
│ ├── ansible.cfg
│ ├── host_vars/
│ │ └── pfsense-test.yml
│ ├── hosts
│ ├── openvpn.yml
│ ├── tasks/
│ │ ├── test_interface_create.yml
│ │ ├── test_interface_group_create.yml
│ │ ├── test_interface_group_ifconfig_groups.yml
│ │ ├── test_openvpn_override_create.yml
│ │ ├── test_openvpn_override_delete.yml
│ │ ├── test_openvpn_override_file_exists.yml
│ │ ├── test_openvpn_server_create.yml
│ │ └── test_openvpn_server_delete.yml
│ └── templates/
│ ├── openvpn-override.j2
│ └── openvpn-server-config.ovpn.j2
├── sanity/
│ ├── ignore-2.14.txt
│ ├── ignore-2.15.txt
│ ├── ignore-2.16.txt
│ └── ignore-2.17.txt
└── unit/
└── plugins/
├── lookup/
│ └── test_pfsense.py
├── module_utils/
│ ├── fixtures/
│ │ └── pfsense_setup_config.xml
│ └── test_pfsense.py
└── modules/
├── __init__.py
├── fixtures/
│ ├── 2.4/
│ │ ├── pfsense_ipsec_aggregate_config.xml
│ │ ├── pfsense_ipsec_config.xml
│ │ └── pfsense_ipsec_proposal_config.xml
│ ├── pfsense_aggregate_config.xml
│ ├── pfsense_alias_config.xml
│ ├── pfsense_alias_null_config.xml
│ ├── pfsense_authserver_config.xml
│ ├── pfsense_ca_config.xml
│ ├── pfsense_cert_config.xml
│ ├── pfsense_dhcp_server_config.xml
│ ├── pfsense_dhcp_static_config.xml
│ ├── pfsense_dns_resolver_config_full.xml
│ ├── pfsense_dns_resolver_config_init.xml
│ ├── pfsense_gateway_config.xml
│ ├── pfsense_haproxy_backend_config.xml
│ ├── pfsense_haproxy_backend_server_config.xml
│ ├── pfsense_interface_config.xml
│ ├── pfsense_ipsec_aggregate_config.xml
│ ├── pfsense_ipsec_config.xml
│ ├── pfsense_ipsec_p2_config.xml
│ ├── pfsense_ipsec_proposal_config.xml
│ ├── pfsense_nat_outbound.xml
│ ├── pfsense_nat_port_forward_config.xml
│ ├── pfsense_openvpn_config.xml
│ ├── pfsense_route_config.xml
│ ├── pfsense_rule_config.xml
│ ├── pfsense_rule_separator_config.xml
│ ├── pfsense_setup_config.xml
│ ├── pfsense_syslog_config.xml
│ ├── pfsense_user_config.xml
│ └── pfsense_vlan_config.xml
├── pfsense_module.py
├── test_pfsense_aggregate.py
├── test_pfsense_alias.py
├── test_pfsense_alias_null.py
├── test_pfsense_authserver_ldap.py
├── test_pfsense_authserver_radius.py
├── test_pfsense_ca.py
├── test_pfsense_cert.py
├── test_pfsense_dhcp_server.py
├── test_pfsense_dhcp_static.py
├── test_pfsense_dns_resolver.py
├── test_pfsense_gateway.py
├── test_pfsense_haproxy_backend.py
├── test_pfsense_haproxy_backend_server.py
├── test_pfsense_interface.py
├── test_pfsense_interface_group.py
├── test_pfsense_ipsec.py
├── test_pfsense_ipsec_aggregate.py
├── test_pfsense_ipsec_p2.py
├── test_pfsense_ipsec_proposal.py
├── test_pfsense_log_settings.py
├── test_pfsense_nat_outbound.py
├── test_pfsense_nat_port_forward.py
├── test_pfsense_openvpn_override.py
├── test_pfsense_openvpn_server.py
├── test_pfsense_route.py
├── test_pfsense_rule.py
├── test_pfsense_rule_create.py
├── test_pfsense_rule_misc.py
├── test_pfsense_rule_noop.py
├── test_pfsense_rule_separator.py
├── test_pfsense_rule_update.py
├── test_pfsense_setup.py
├── test_pfsense_user.py
└── test_pfsense_vlan.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: opoplawski # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
#patreon: # Replace with a single Patreon username
#open_collective: # Replace with a single Open Collective username
#ko_fi: # Replace with a single Ko-fi username
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
#liberapay: # Replace with a single Liberapay username
#issuehunt: # Replace with a single IssueHunt username
#lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
#polar: # Replace with a single Polar username
#buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
#thanks_dev: # Replace with a single thanks.dev username
#custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Playbook**
Please paste a minimal playbook to reproduce the issue:
```
```
**Output**
Please paste the ansible output run with `-vv`:
```
```
**Environment**
- What version of pfsensible.core?
- What version of ansible?
- What version of pfSense?
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/workflows/main.yml
================================================
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events
push:
pull_request:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
# ubuntu-latest fails: https://github.com/actions/runner/issues/2364
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.10']
ansible-version: ['2.14', '2.15', '2.16', '2.17']
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout project
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip modules
uses: actions/cache@v4
env:
cache-name: cache-pip
with:
path: |
~/.cache
key: ${{ runner.os }}-build-${{ env.cache-name }}-python-${{ matrix.python-version }}
- name: Cache ansible setup
uses: actions/cache@v4
env:
cache-name: cache-ansible
with:
path: |
~/work/ansible-pfsense/ansible-pfsense/ansible
key: build-${{ env.cache-name }}-ansible-${{ matrix.ansible-version }}
# Runs a set of commands using the runners shell
- name: Install ansible and deps
run: |
pip install ansible-core==${{ matrix.ansible-version }}.* dnspython parameterized pyyaml
ansible-galaxy collection install community.internal_test_tools
- name: Run ansible tests
run: |
pwd
dir=$(pwd)
mkdir -p ~/.ansible/collections/ansible_collections/pfsensible
cd ~/.ansible/collections/ansible_collections/pfsensible
cp -al $dir core
cd core
ansible-test sanity --requirements --python ${{ matrix.python-version }}
ansible-test units --requirements --python ${{ matrix.python-version }}
================================================
FILE: .gitignore
================================================
# test output
tests/output/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# ansible-galaxy package
*.tar.gz
# vi
*.swp
================================================
FILE: CHANGELOG.rst
================================================
=============================
pfSensible.Core Release Notes
=============================
.. contents:: Topics
v0.7.1
======
Minor Changes
-------------
- pfsense_ipsec_p2/proposal - Add missing new DH Groups 31, 32 support in ipsec vpn (https://github.com/pfsensible/core/issues/183)
- pfsense_log_settings - add nologlinklocal4, nologsnort2c, and logconfigchanges parameters (https://github.com/pfsensible/core/pull/199).
- pfsense_user - add disabled parameter (https://github.com/pfsensible/core/pull/208).
Bugfixes
--------
- pfsense_aggregate - fix argument_spec handling for aggregated modules that broke aggregated_nat_outbounds (https://github.com/pfsensible/core/issues/201).
- pfsense_authserver_ldap - Call set_pam_auth() if needed to update system config.
- pfsense_authserver_ldap - Fix disabling ldap_allow_unauthenticated (https://github.com/pfsensible/core/issues/139).
- pfsense_ca - Better validation for name, lifetime, and dn_* parameters (https://github.com/pfsensible/core/pull/142).
- pfsense_dhcp_server - Describe denyunknown options and allow disabling it via `disabled` (https://github.com/pfsensible/core/issues/203).
- pfsense_dns_resolver - Add ability to specify Virtual IPs for interfaces (https://github.com/pfsensible/core/issues/136).
- pfsense_dns_resolver - Fix configuration without domainoverrides set (https://github.com/pfsensible/core/issues/206).
- pfsense_dns_resolver - Fix forward_tls_upstream handling in domainoverrides (https://github.com/pfsensible/core/issues/209).
- pfsense_ipsec_p2 - Allow disabling hash algorithms (https://github.com/pfsensible/core/issues/172)
- pfsense_setup - Fix PHP command to update system broken in 0.7.0 (https://github.com/pfsensible/core/pull/210).
v0.7.0
======
Release Summary
---------------
This is a major refactoring of the ``pfsensible.core`` collection. The goal
was to support easier creation of new modules via the ``pfsensible-generate-module``
script. PFSenseModuleBase was expanded to handle more common functions via
configuration options and callback functions.
Minor Changes
-------------
- pfsense_alias - Add `url` parameter and deprecate using `address` for `urltable` and `urltable_ports` types.
- pfsense_ca - Add ability to create internal CAs. (https://github.com/pfsensible/core/issues/135)
- pfsense_rule - Change `after` to insert after the last match instead of the first.
Breaking Changes / Porting Guide
--------------------------------
- This release is only expected to work with pfSense 2.8.0+ / pfSense Plus 24.11+ due to changes in various lookup_*() functions in pfSense.
Bugfixes
--------
- Use config_get_path() to load configuration in php update commands. Fixes various update commands not working with pfSense 2.8.0 (https://github.com/pfsensible/core/issues/190)
- pfsense_ca / pfsense_cert - Fix validation of base64 encoded keys and certs. (https://github.com/pfsensible/core/issues/174)
- pfsense_ca/pfsense_cert - Restart services affected by updated certificates. (https://github.com/pfsensible/core/issues/191)
- pfsense_cert - Write generated internal certificate into config. (https://github.com/pfsensible/core/issues/186)
- pfsense_dns_resolver - do not always add an empty domainoverrides item. (https://github.com/pfsensible/core/issues/187)
- pfsense_interface - fixes removal of an interface when interface group is empty. (https://github.com/pfsensible/core/issues/182)
- pfsense_interface - fixes removal of an interface with `state: absent`. _remove_all_separators() works when no separator exists for that interface. (https://github.com/pfsensible/core/issues/170)
New Modules
-----------
- pfsensible.core.pfsense_dhcp_server - Manage pfSense DHCP servers
- pfsensible.core.pfsense_phpshell - PHP Shell
- pfsensible.core.pfsense_shellcmd - Manage pfSense shellcmds
v0.6.2
======
Minor Changes
-------------
- added ``auto`` choice for ``myid_type`` and ``peerid_type`` (https://github.com/pfsensible/core/issues/145)
- pfsense_ca - added ``key`` parameter to import CA private key (https://github.com/pfsensible/core/issues/57)
- pfsense_dns_resolver - validate ``domainoverrides.ip`` field
- pfsense_openvpn_client - added ``v4only`` and `v6only`` values for ``create_gw`` (https://github.com/pfsensible/core/issues/133)
- pfsense_openvpn_override - support changed semantics of ``push_reset`` in pfSense Plus 24.11
- pfsense_openvpn_server - no longer sort authmode items
- pfsense_setup - Update language list for pfSense 2.7.1 / pfSense Plus 23.09.
- pfsensible_interface - implemented ``ipv6_type: slaac`` and added the ``slaacusev4iface`` parameter (https://github.com/pfsensible/core/issues/121).
- pfsensible_openvpn_server - Allow ``Local Database`` for ``authmode`` parameter (https://github.com/pfsensible/core/issues/125).
Bugfixes
--------
- made pfsense_dns_resolver hosts idempotent (https://github.com/pfsensible/core/issues/151)
- pfsense - handle "."s prefixing php() output triggered by the presense of /var/run/booting and issue a warning (https://github.com/pfsensible/core/issues/118)
- pfsense_dns_resolver - allow for comma separated list of IP addresses in ``hosts.ip`` (https://github.com/pfsensible/core/discussions/150)
- pfsense_openvpn_client - add ``tls_type`` parameter
- pfsense_openvpn_client/server - apply ``tls`` setting to config (https://github.com/pfsensible/core/issues/132)
- pfsense_user - fixed setting multiple groups for a user (https://github.com/pfsensible/core/issues/130)
- set `global $config;` in phpshell() to find update commands in pfSense Plus 24.11
v0.6.1
======
Minor Changes
-------------
- Bump required ansible version to 2.12.
- Have _get_ansible_param_bool set the value to value_false if the parameter is present and false.
- Refactor pfsense_authserver_ldap and pfsense_authserver_radius. Should not have any visible impact.
- Ship tests so other pfsensible collections can use them.
- pfsense_ca - allow for disabling `randomserial` and `trust` parameters.
- pfsense_dhcp_static - Add arp_table_static_entry argument (https://github.com/https://github.com/pfsensible/core/issues/109).
Deprecated Features
-------------------
- The pfsensible_haproxy* modules have moved to the `pfsensible.haproxy` collection and will be removed from `pfsensible.core` in version 0.8.0.
v0.6.0
======
Major Changes
-------------
- pfsense_default_gateway - Add module for setting the default gateways
- pfsense_dns_resolver - Add module for DNS resolver (unbound) settings
Minor Changes
-------------
- ipaddress support for pfSense 2.4.4
- pfsense_cert - Support EC certs (https://github.com/pfsensible/core/pull/98)
- pfsense_interface - Always return `ifname` - even on interface creation
- pfsense_interface - Prevent removal if interface is part of an interface group
- pfsense_nat_outbound - Allow for NET:INTERFACE addresses
- pfsense_nat_port_forward - 2.4.5 compatibility
- pfsense_openvpn_server - Do not allow removal of an instance with an interface assignment
- pfsense_rule - Add option to ignore an inexistent queue
- pfsense_rule - Add support for floating 'any' interface rule (https://github.com/pfsensible/core/pull/90)
- plugins/lookup/pfsense - Optimization and ignore queue setting
- tests/plays - Add plays for testing with a live pfSense instance
Bugfixes
--------
- pfsense_aggregate - Fix where a rule with a duplicated name would not be deleted if required
- pfsense_dhcp_static - Allow removing entry with just name (https://github.com/pfsensible/core/issues/69)
- pfsense_dhcp_static - Allow use of display name for netif. Error in case a interface group name is specified (https://github.com/pfsensible/core/issues/79)
- pfsense_interface - Properly shut dwon interface and kill dhclient process when removing interface (https://github.com/pfsensible/core/pull/67)
- pfsense_interface_group - Check that members list is unique
- pfsense_interface_group - Fix creation (https://github.com/pfsensible/core/issues/74)
- pfsense_interface_group - `members` is only required for creation
- pfsense_nat_outbound - Fix boolean values, invert (https://github.com/pfsensible/core/issues/92)
- pfsense_openvpn_client - Fix strictuserdn -> strictusercn option (https://github.com/pfsensible/core/pull/93)
- pfsense_openvpn_client/override/server - Allow network alias and non-strict network address for `tunnel_network`/`tunnel_network6` (https://github.com/pfsensible/core/issues/77)
- pfsense_openvpn_server - Fix use of `generate` with `shared_key` and `tls` (https://github.com/pfsensible/core/issues/81)
- pfsense_setup - No default values - leads to unexpected changes (https://github.com/pfsensible/core/issues/91)
- pfsense_user - Fix setting system group membership (https://github.com/pfsensible/core/issues/70)
New Modules
-----------
- pfsensible.core.pfsense_default_gateway - Manage pfSense default gateway
- pfsensible.core.pfsense_dns_resolver - Manage pfSense DNS resolver (unbound) settings
================================================
FILE: GENERATING_MODULES.md
================================================
# Generating Modules with pfsensible-generate-module
The process of writing basic pfsensible modules is hopefully greatly simplified by using
the pfsensible-generate-module script. The basic workflow is as follows:
* You need a test pfSense instance with ssh access enabled.
* Navigate in the pfSense web interface to the area you want to write a module for. This should be a page where you can edit
settings or one where you are adding an item.
* Copy the URL of the page - you will pass it to the `--url` option of the script.
## Modules that manage multiple items
If this is a module that will allow you to create multiple items (e.g. aliases, rules):
* Save a minimal item with a name (often Name or Description) of `item_min` (or something else if that does not work).
Simply try immediately saving an item with just that name, then fill out fields one at a time and re-save until pfSense
stops complaining about missing items.
* Save a "fully" configured item with a name of `item_full` (or something else if that will not work). It may be
helpful to change as many options away from the default as possible. Focus on settings that would be useful to you.
* Run the script:
misc/pfsensible-generate-module --url URL
if you needed to use different names for the items than `item_min` and `item_full` you can set them with the `--item-min` and
`--item-full` options.
## Modules that configure something
If this is a module that will just configure something, it is best to start with the default configuration. Then add the
--is-config` option:
misc/pfsensible-generate-module --url URL --is-config
## Other options
* Pass the `--author-name`, `--author-email`, and `--author-handle` options to give yourself credit!
* You will need to add the `--user` and/or `--password` options if you have changed from the install defaults.
* If the automatically determined module name does not seem correct, you can change it with the `--module-name` option.
* It may make sense to create a module for different types of items if the parameters are wildly different (as is the case
with the different types of authentication servers for example). If so, add the `--type-suffix` option to add the "type"
of the item as a suffix to the module name.
## Final steps
Review the items in the generated module flagged with `TODO` for possible changes needed.
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# ansible-pfsense / pfsensible.core
This is a set of modules to allow you to configure pfSense firewalls with ansible.
### NOTE: Changes with pfsensible.core 0.4.0
With pfsensible.core 0.4.0 we have stopped stripping the pfsense_ prefix from the module names. This caused conflicts with other
modules (like the ansible core 'setup' module). You can use the ['collections'](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html#simplifying-module-names-with-the-collections-keyword)
keyword in your playbooks and roles to simplify the module names instead.
## Installation using ansible galaxy
Ansible Galaxy (as of version 2.9) now has an option for collections. A collection is a distribution
format for delivering all type of Ansible content (not just roles as it was before). To install:
```
ansible-galaxy collection install pfsensible.core
```
Optionally, you can specify the path of the collection installation with the `-p` option.
```
ansible-galaxy collection install pfsensible.core -p ./collections
```
Additionally, you can set the `collections_paths` option in your `ansible.cfg` file to automatically designate install locations.
```ini
# ansible.cfg
[defaults]
collections_paths=collections
```
## Configuration
Current versions of ansible should automatically detect the version of Python on the pfSense system. If Python discovery fails, you can set
ansible_python_interpreter in your playbook or hosts vars, e.g. for pfSense 2.7.2:
```
ansible_python_interpreter: /usr/local/bin/python3.11
```
Modules must run as root in order to make changes to the system. By default pfSense does not have sudo capability so `become` will not work. You can install it with:
```
- name: "Install packages"
package:
name:
- pfSense-pkg-sudo
state: present
```
and then configure sudo so that your user has permission to use sudo.
## Modules
The following modules are currently available:
* [pfsense_alias](https://github.com/pfsensible/core/wiki/pfsense_alias) for aliases
* [pfsense_authserver_ldap](https://github.com/pfsensible/core/wiki/pfsense_authserver_ldap) for LDAP authentication servers
* [pfsense_authserver_radius](https://github.com/pfsensible/core/wiki/pfsense_authserver_radius) for RADIUS authentication servers
* [pfsense_ca](https://github.com/pfsensible/core/wiki/pfsense_ca) for Certificate Authorities
* [pfsense_cert](https://github.com/pfsensible/core/wiki/pfsense_cert) for Certificates
* [pfsense_default_gateway](https://github.com/pfsensible/core/wiki/pfsense_default_gateway) for setting the default gateways
* [pfsense_dhcp_static](https://github.com/pfsensible/core/wiki/pfsense_dhcp_static) for static DHCP entries
* [pfsense_dns_resolver](https://github.com/pfsensible/core/wiki/pfsense_dns_resolver) for DNS resolver (unbound) settings
* [pfsense_gateway](https://github.com/pfsensible/core/wiki/pfsense_gateway) for routing gateways
* [pfsense_group](https://github.com/pfsensible/core/wiki/pfsense_group) for user groups
* [pfsense_interface](https://github.com/pfsensible/core/wiki/pfsense_interface) for interfaces
* [pfsense_interface_group](https://github.com/pfsensible/core/wiki/pfsense_interface_group) for interface groups
* [pfsense_ipsec](https://github.com/pfsensible/core/wiki/pfsense_ipsec) for IPsec tunnels and phase 1 options
* [pfsense_ipsec_proposal](https://github.com/pfsensible/core/wiki/pfsense_ipsec_proposal) for IPsec proposals
* [pfsense_ipsec_p2](https://github.com/pfsensible/core/wiki/pfsense_ipsec_p2) for IPsec tunnels phase 2 options
* [pfsense_log_settings](https://github.com/pfsensible/core/wiki/pfsense_log_settings) for logging settings
* [pfsense_openvpn_client](https://github.com/pfsensible/core/wiki/pfsense_openvpn_client) for OpenVPN client configuration
* [pfsense_openvpn_override](https://github.com/pfsensible/core/wiki/pfsense_openvpn_override) for OpenVPN override configuration
* [pfsense_openvpn_server](https://github.com/pfsensible/core/wiki/pfsense_openvpn_server) for OpenVPN server configuration
* [pfsense_nat_outbound](https://github.com/pfsensible/core/wiki/pfsense_nat_outbound) for outbound NAT (SNAT) rules
* [pfsense_nat_port_forward](https://github.com/pfsensible/core/wiki/pfsense_nat_port_forward) for port forwarding NAT (DNAT) rules
* [pfsense_rewrite_config](https://github.com/pfsensible/core/wiki/pfsense_rewrite_config) to rewrite config.xml
* [pfsense_route](https://github.com/pfsensible/core/wiki/pfsense_route) for routes
* [pfsense_rule](https://github.com/pfsensible/core/wiki/pfsense_rule) for firewall rules
* [pfsense_rule_separator](https://github.com/pfsensible/core/wiki/pfsense_rule_separator) for firewall rule separators
* [pfsense_setup](https://github.com/pfsensible/core/wiki/pfsense_setup) for general setup
* [pfsense_user](https://github.com/pfsensible/core/wiki/pfsense_user) for users
* [pfsense_vlan](https://github.com/pfsensible/core/wiki/pfsense_vlan) for VLANs
## Bulk modules
These modules allow you to make important changes at once and, using the purge parameters, to keep the targets configuration strictly synchronized with your playbooks:
* [pfsense_aggregate](https://github.com/pfsensible/core/wiki/pfsense_aggregate) for firewall aliases, rules, and rule separators, plus interfaces and VLANs
* [pfsense_ipsec_aggregate](https://github.com/pfsensible/core/wiki/pfsense_ipsec_aggregate) for IPsec tunnels, phases 1, phases 2 and proposals
## Third party modules
These modules allow you to manage installed packages:
* [pfsense_haproxy_backend](https://github.com/pfsensible/core/wiki/pfsense_haproxy_backend) for HAProxy backends
* [pfsense_haproxy_backend_server](https://github.com/pfsensible/core/wiki/pfsense_haproxy_backend_server) for HAProxy backends servers
## [Change Log](https://github.com/pfsensible/core/blob/master/CHANGELOG.rst)
## High-Availability Configuration Syncing
pfsensible modules do not trigger an XMLRPC configuration sync to a secondary system. But this can be done with the use of a handler as shown:
```
tasks:
- name: Make a chage
pfsensible.core.alias:
name: an_alias
state: absent
become: true
notify: sync config
handlers:
- name: sync config
pfsensible.core.pfsense_rewrite_config:
become: true
```
## Writing new modules
See [GENERATING_MODULES](https://github.com/pfsensible/core/blob/master/GENERATING_MODULES.md) for instructions on how to use the
pfensible-generate-module script to automate the task writing basic pfsensible modules.
## Operation
Modules in the collection work by editing `/cf/conf/config.xml` using xml.etree.ElementTree, then
calling the appropriate PHP update function via the pfSense PHP developer shell.
Some formatting is lost, and CDATA items are converted to normal entries,
but so far no problems with that have been noted.
## License
GPLv3.0 or later
================================================
FILE: changelogs/.plugin-cache.yaml
================================================
objects: {}
plugins:
become: {}
cache: {}
callback: {}
cliconf: {}
connection: {}
httpapi: {}
inventory: {}
lookup:
pfsense:
description: Generate pfSense aliases, rules and rule_separators
name: pfsense
version_added: 0.1.0
module:
pfsense_aggregate:
description: Manage multiple pfSense firewall aliases, rules, and rule separators,
plus interfaces and VLANs
name: pfsense_aggregate
namespace: ''
version_added: 0.1.0
pfsense_alias:
description: Manage pfSense aliases
name: pfsense_alias
namespace: ''
version_added: 0.1.0
pfsense_authserver_ldap:
description: Manage pfSense LDAP authentication servers
name: pfsense_authserver_ldap
namespace: ''
version_added: 0.1.0
pfsense_authserver_radius:
description: Manage pfSense RADIUS authentication servers
name: pfsense_authserver_radius
namespace: ''
version_added: 0.5.0
pfsense_ca:
description: Manage pfSense Certificate Authorities
name: pfsense_ca
namespace: ''
version_added: 0.1.0
pfsense_cert:
description: Manage pfSense certificates
name: pfsense_cert
namespace: ''
version_added: 0.5.0
pfsense_default_gateway:
description: Manage pfSense default gateway
name: pfsense_default_gateway
namespace: ''
version_added: 0.6.0
pfsense_dhcp_server:
description: Manage pfSense DHCP servers
name: pfsense_dhcp_server
namespace: ''
version_added: 0.7.0
pfsense_dhcp_static:
description: Manage pfSense DHCP static mapping
name: pfsense_dhcp_static
namespace: ''
version_added: 0.5.0
pfsense_dns_resolver:
description: Manage pfSense DNS resolver (unbound) settings
name: pfsense_dns_resolver
namespace: ''
version_added: 0.6.0
pfsense_gateway:
description: Manage pfSense gateways
name: pfsense_gateway
namespace: ''
version_added: 0.1.0
pfsense_group:
description: Manage pfSense user groups
name: pfsense_group
namespace: ''
version_added: 0.1.0
pfsense_haproxy_backend:
description: Manage pfSense HAProxy backends
name: pfsense_haproxy_backend
namespace: ''
version_added: 0.1.0
pfsense_haproxy_backend_server:
description: Manage pfSense haproxy backend servers
name: pfsense_haproxy_backend_server
namespace: ''
version_added: 0.1.0
pfsense_interface:
description: Manage pfSense interfaces
name: pfsense_interface
namespace: ''
version_added: 0.1.0
pfsense_interface_group:
description: Manage pfSense interface groups
name: pfsense_interface_group
namespace: ''
version_added: 0.5.0
pfsense_ipsec:
description: Manage pfSense IPsec tunnels and phase 1 options
name: pfsense_ipsec
namespace: ''
version_added: 0.1.0
pfsense_ipsec_aggregate:
description: Manage multiple pfSense IPsec tunnels, phases 1, phases 2 and proposals
name: pfsense_ipsec_aggregate
namespace: ''
version_added: 0.1.0
pfsense_ipsec_p2:
description: Manage pfSense IPsec tunnels phase 2 options
name: pfsense_ipsec_p2
namespace: ''
version_added: 0.1.0
pfsense_ipsec_proposal:
description: Manage pfSense IPsec proposals
name: pfsense_ipsec_proposal
namespace: ''
version_added: 0.1.0
pfsense_log_settings:
description: Manage pfSense syslog settings
name: pfsense_log_settings
namespace: ''
version_added: 0.4.2
pfsense_nat_outbound:
description: Manage pfSense Outbound NAT (SNAT) rules
name: pfsense_nat_outbound
namespace: ''
version_added: 0.1.0
pfsense_nat_port_forward:
description: Manage pfSense port forwarding NAT (DNAT) rules
name: pfsense_nat_port_forward
namespace: ''
version_added: 0.1.0
pfsense_openvpn_client:
description: Manage pfSense OpenVPN configuration
name: pfsense_openvpn_client
namespace: ''
version_added: 0.5.0
pfsense_openvpn_override:
description: Manage pfSense OpenVPN Client Specific Overrides
name: pfsense_openvpn_override
namespace: ''
version_added: 0.5.0
pfsense_openvpn_server:
description: Manage pfSense OpenVPN server configuration
name: pfsense_openvpn_server
namespace: ''
version_added: 0.5.0
pfsense_phpshell:
description: PHP Shell
name: pfsense_phpshell
namespace: ''
version_added: 0.7.0
pfsense_rewrite_config:
description: Rewrite pfSense config.xml
name: pfsense_rewrite_config
namespace: ''
version_added: 0.5.3
pfsense_route:
description: Manage pfSense routes
name: pfsense_route
namespace: ''
version_added: 0.1.0
pfsense_rule:
description: Manage pfSense firewall rules
name: pfsense_rule
namespace: ''
version_added: 0.1.0
pfsense_rule_separator:
description: Manage pfSense firewall rule separators
name: pfsense_rule_separator
namespace: ''
version_added: 0.1.0
pfsense_setup:
description: Manage pfSense general setup
name: pfsense_setup
namespace: ''
version_added: 0.1.0
pfsense_shellcmd:
description: Manage pfSense shellcmds
name: pfsense_shellcmd
namespace: ''
version_added: 0.7.0
pfsense_user:
description: Manage pfSense users
name: pfsense_user
namespace: ''
version_added: 0.1.0
pfsense_vlan:
description: Manage pfSense VLANs
name: pfsense_vlan
namespace: ''
version_added: 0.1.0
netconf: {}
shell: {}
strategy: {}
vars: {}
version: 0.7.1
================================================
FILE: changelogs/134_openvpn_digest.yml
================================================
bugfixes:
- pfsense_openvpn_client/server - Support additional digest values
(https://github.com/pfsensible/core/issues/134).
================================================
FILE: changelogs/changelog.yaml
================================================
ancestor: null
releases:
0.6.0:
changes:
bugfixes:
- pfsense_aggregate - Fix where a rule with a duplicated name would not be deleted
if required
- pfsense_dhcp_static - Allow removing entry with just name (https://github.com/pfsensible/core/issues/69)
- pfsense_dhcp_static - Allow use of display name for netif. Error in case a
interface group name is specified (https://github.com/pfsensible/core/issues/79)
- pfsense_interface - Properly shut dwon interface and kill dhclient process
when removing interface (https://github.com/pfsensible/core/pull/67)
- pfsense_interface_group - Check that members list is unique
- pfsense_interface_group - Fix creation (https://github.com/pfsensible/core/issues/74)
- pfsense_interface_group - `members` is only required for creation
- pfsense_nat_outbound - Fix boolean values, invert (https://github.com/pfsensible/core/issues/92)
- pfsense_openvpn_client - Fix strictuserdn -> strictusercn option (https://github.com/pfsensible/core/pull/93)
- pfsense_openvpn_client/override/server - Allow network alias and non-strict
network address for `tunnel_network`/`tunnel_network6` (https://github.com/pfsensible/core/issues/77)
- pfsense_openvpn_server - Fix use of `generate` with `shared_key` and `tls`
(https://github.com/pfsensible/core/issues/81)
- pfsense_setup - No default values - leads to unexpected changes (https://github.com/pfsensible/core/issues/91)
- pfsense_user - Fix setting system group membership (https://github.com/pfsensible/core/issues/70)
major_changes:
- pfsense_default_gateway - Add module for setting the default gateways
- pfsense_dns_resolver - Add module for DNS resolver (unbound) settings
minor_changes:
- ipaddress support for pfSense 2.4.4
- pfsense_cert - Support EC certs (https://github.com/pfsensible/core/pull/98)
- pfsense_interface - Always return `ifname` - even on interface creation
- pfsense_interface - Prevent removal if interface is part of an interface group
- pfsense_nat_outbound - Allow for NET:INTERFACE addresses
- pfsense_nat_port_forward - 2.4.5 compatibility
- pfsense_openvpn_server - Do not allow removal of an instance with an interface
assignment
- pfsense_rule - Add option to ignore an inexistent queue
- pfsense_rule - Add support for floating 'any' interface rule (https://github.com/pfsensible/core/pull/90)
- plugins/lookup/pfsense - Optimization and ignore queue setting
- tests/plays - Add plays for testing with a live pfSense instance
fragments:
- 0.6.0-changes.yaml
modules:
- description: Manage pfSense default gateway
name: pfsense_default_gateway
namespace: ''
- description: Manage pfSense DNS resolver (unbound) settings
name: pfsense_dns_resolver
namespace: ''
release_date: '2024-01-06'
0.6.1:
changes:
deprecated_features:
- The pfsensible_haproxy* modules have moved to the `pfsensible.haproxy` collection
and will be removed from `pfsensible.core` in version 0.8.0.
minor_changes:
- Bump required ansible version to 2.12.
- Have _get_ansible_param_bool set the value to value_false if the parameter
is present and false.
- Refactor pfsense_authserver_ldap and pfsense_authserver_radius. Should not
have any visible impact.
- Ship tests so other pfsensible collections can use them.
- pfsense_ca - allow for disabling `randomserial` and `trust` parameters.
- pfsense_dhcp_static - Add arp_table_static_entry argument (https://github.com/https://github.com/pfsensible/core/issues/109).
fragments:
- 111-Add-arp_table-static_entry.yml
- ansible-requires.yml
- authserver-refactor.yml
- deprecate_haproxy.yml
- module-base-bool.yml
- pfsense_ca-allow-disabling.yml
- ship-tests.yml
release_date: '2024-01-20'
0.6.2:
changes:
bugfixes:
- made pfsense_dns_resolver hosts idempotent (https://github.com/pfsensible/core/issues/151)
- pfsense - handle "."s prefixing php() output triggered by the presense of
/var/run/booting and issue a warning (https://github.com/pfsensible/core/issues/118)
- pfsense_dns_resolver - allow for comma separated list of IP addresses in ``hosts.ip``
(https://github.com/pfsensible/core/discussions/150)
- pfsense_openvpn_client - add ``tls_type`` parameter
- pfsense_openvpn_client/server - apply ``tls`` setting to config (https://github.com/pfsensible/core/issues/132)
- pfsense_user - fixed setting multiple groups for a user (https://github.com/pfsensible/core/issues/130)
- set `global $config;` in phpshell() to find update commands in pfSense Plus
24.11
minor_changes:
- added ``auto`` choice for ``myid_type`` and ``peerid_type`` (https://github.com/pfsensible/core/issues/145)
- pfsense_ca - added ``key`` parameter to import CA private key (https://github.com/pfsensible/core/issues/57)
- pfsense_dns_resolver - validate ``domainoverrides.ip`` field
- pfsense_openvpn_client - added ``v4only`` and `v6only`` values for ``create_gw``
(https://github.com/pfsensible/core/issues/133)
- pfsense_openvpn_override - support changed semantics of ``push_reset`` in
pfSense Plus 24.11
- pfsense_openvpn_server - no longer sort authmode items
- pfsense_setup - Update language list for pfSense 2.7.1 / pfSense Plus 23.09.
- 'pfsensible_interface - implemented ``ipv6_type: slaac`` and added the ``slaacusev4iface``
parameter (https://github.com/pfsensible/core/issues/121).'
- pfsensible_openvpn_server - Allow ``Local Database`` for ``authmode`` parameter
(https://github.com/pfsensible/core/issues/125).
fragments:
- booting.yml
- ca_key.yml
- dnf_resolver_aliases.yml
- dns_resolver_ip.yml
- interface-slaac.yml
- ipsec_auto.yml
- langauages.yml
- openvpn_client_gw.yml
- openvpn_localdb.yml
- openvpn_override.yml
- openvpn_server_unsorted_authmode.yml
- openvpn_tls.yml
- phpshell_config.yml
- user_groups.yml
release_date: '2025-01-30'
0.7.0:
changes:
breaking_changes:
- This release is only expected to work with pfSense 2.8.0+ / pfSense Plus 24.11+
due to changes in various lookup_*() functions in pfSense.
bugfixes:
- Use config_get_path() to load configuration in php update commands. Fixes
various update commands not working with pfSense 2.8.0 (https://github.com/pfsensible/core/issues/190)
- pfsense_ca / pfsense_cert - Fix validation of base64 encoded keys and certs.
(https://github.com/pfsensible/core/issues/174)
- pfsense_ca/pfsense_cert - Restart services affected by updated certificates.
(https://github.com/pfsensible/core/issues/191)
- pfsense_cert - Write generated internal certificate into config. (https://github.com/pfsensible/core/issues/186)
- pfsense_dns_resolver - do not always add an empty domainoverrides item. (https://github.com/pfsensible/core/issues/187)
- pfsense_interface - fixes removal of an interface when interface group is
empty. (https://github.com/pfsensible/core/issues/182)
- 'pfsense_interface - fixes removal of an interface with `state: absent`. _remove_all_separators()
works when no separator exists for that interface. (https://github.com/pfsensible/core/issues/170)'
minor_changes:
- pfsense_alias - Add `url` parameter and deprecate using `address` for `urltable`
and `urltable_ports` types.
- pfsense_ca - Add ability to create internal CAs. (https://github.com/pfsensible/core/issues/135)
- pfsense_rule - Change `after` to insert after the last match instead of the
first.
release_summary: 'This is a major refactoring of the ``pfsensible.core`` collection. The
goal
was to support easier creation of new modules via the ``pfsensible-generate-module``
script. PFSenseModuleBase was expanded to handle more common functions via
configuration options and callback functions.'
fragments:
- 0.7.0.yml
- 135_pfsense_ca_create_internal.yml
- 170_pfsense_interface_fix_remove_all_separators.yml
- 174_pfsense_cert_validate_base64.yml
- 182_interface_group_null_check.yml
- 186_fix_pfsense_cert_internal.yml
- 187_dns_resolver_domainoverrides.yml
- 190_config_get_path.yml
- 191_cert_restart_services.yml
- pfsense_alias-add-url.yml
- pfsense_rule-after.yml
modules:
- description: Manage pfSense DHCP servers
name: pfsense_dhcp_server
namespace: ''
- description: PHP Shell
name: pfsense_phpshell
namespace: ''
- description: Manage pfSense shellcmds
name: pfsense_shellcmd
namespace: ''
release_date: '2025-09-22'
0.7.1:
changes:
bugfixes:
- pfsense_aggregate - fix argument_spec handling for aggregated modules that
broke aggregated_nat_outbounds (https://github.com/pfsensible/core/issues/201).
- pfsense_authserver_ldap - Call set_pam_auth() if needed to update system config.
- pfsense_authserver_ldap - Fix disabling ldap_allow_unauthenticated (https://github.com/pfsensible/core/issues/139).
- pfsense_ca - Better validation for name, lifetime, and dn_* parameters (https://github.com/pfsensible/core/pull/142).
- pfsense_dhcp_server - Describe denyunknown options and allow disabling it
via `disabled` (https://github.com/pfsensible/core/issues/203).
- pfsense_dns_resolver - Add ability to specify Virtual IPs for interfaces (https://github.com/pfsensible/core/issues/136).
- pfsense_dns_resolver - Fix configuration without domainoverrides set (https://github.com/pfsensible/core/issues/206).
- pfsense_dns_resolver - Fix forward_tls_upstream handling in domainoverrides
(https://github.com/pfsensible/core/issues/209).
- pfsense_ipsec_p2 - Allow disabling hash algorithms (https://github.com/pfsensible/core/issues/172)
- pfsense_setup - Fix PHP command to update system broken in 0.7.0 (https://github.com/pfsensible/core/pull/210).
minor_changes:
- pfsense_ipsec_p2/proposal - Add missing new DH Groups 31, 32 support in ipsec
vpn (https://github.com/pfsensible/core/issues/183)
- pfsense_log_settings - add nologlinklocal4, nologsnort2c, and logconfigchanges
parameters (https://github.com/pfsensible/core/pull/199).
- pfsense_user - add disabled parameter (https://github.com/pfsensible/core/pull/208).
fragments:
- 136_dns_resolver_domainoverrides.yml
- 139_ldap_allow_unauthenticated.yml
- 142_ca_validate.yml
- 172_ipsec_hash.yml
- 183_ipsec_dh.yml
- 199_pfsense_log_settings_parameters.yml
- 201_pfsense_aggregate_nat.yml
- 203_dhcp_server_denyunknown.yml
- 206_dns_resolver_domainoverrides.yml
- 208_pfsense_user_disabled.yml
- 209_dns_resolver_domainoverrides.yml
- 210_setup.yml
- pfsense_authserver_ldap_pam.yml
release_date: '2025-11-09'
================================================
FILE: changelogs/config.yaml
================================================
changelog_filename_template: ../CHANGELOG.rst
changelog_filename_version_depth: 0
changes_file: changelog.yaml
changes_format: combined
ignore_other_fragment_extensions: true
keep_fragments: false
mention_ancestor: true
new_plugins_after_name: removed_features
notesdir: fragments
prelude_section_name: release_summary
prelude_section_title: Release Summary
sanitize_changelog: true
sections:
- - major_changes
- Major Changes
- - minor_changes
- Minor Changes
- - breaking_changes
- Breaking Changes / Porting Guide
- - deprecated_features
- Deprecated Features
- - removed_features
- Removed Features (previously deprecated)
- - security_fixes
- Security Fixes
- - bugfixes
- Bugfixes
- - known_issues
- Known Issues
title: pfSensible.Core
trivial_section_name: trivial
use_fqcn: true
================================================
FILE: changelogs/fragments/129_sshguard_whitelist.yaml
================================================
minor_changes:
- pfsense_setup - added sshguard_whitelist option (https://github.com/pfsensible/core/issues/129).
================================================
FILE: changelogs/fragments/217_pfsense_setup_webguicert.yml
================================================
minor_changes:
- pfsense_setup - add ``webguicert`` parameter (https://github.com/pfsensible/core/pull/217).
================================================
FILE: changelogs/fragments/219_parse_address_ipv6.yml
================================================
bugfixes:
- pfsense_rule - Allow IPv6 addresses in source and destination (https://github.com/pfsensible/core/issues/219).
================================================
FILE: changelogs/fragments/223_fix_openvpn_alias_expansion.yml
================================================
minor_changes:
- pfsense_openvpn_server - add call to ``alias_make_table()`` to allow alias expansion (https://github.com/pfsensible/core/pull/223).
================================================
FILE: changelogs/fragments/224_add_dco_for_plus_versions.yml
================================================
minor_changes:
- pfsense_openvpn_server - add ``dco`` parameter (https://github.com/pfsensible/core/pull/224).
- improve pfsense.is_ce_version to better support CE and Plus comparison
================================================
FILE: changelogs/fragments/226_dns_resolver.yaml
================================================
bugfixes:
- pfsense_dns_resolver - Allow IPv6 addresses for hosts and domainoverrides (https://github.com/pfsensible/core/pull/245).
================================================
FILE: changelogs/fragments/228_interface_diff.yml
================================================
minor_changes:
- pfsense_interface - support ``--diff`` (https://github.com/pfsensible/core/pull/228).
================================================
FILE: changelogs/fragments/238_pfsense_openvpn_server.yml
================================================
bugfixes:
- pfsense_openvpn_server - Normalize `tls` text to CRLF line endings to match web interface (https://github.com/pfsensible/core/issues/163).
minor_changes:
- pfsense_openvpn_server - Drop `ncp_enable` parameter no longer used (https://github.com/pfsensible/core/pull/238).
- pfsense_openvpn_server - No longer remove `strictusercn` option if not specified to match web interface (https://github.com/pfsensible/core/pull/238).
================================================
FILE: changelogs/fragments/239_sync_config.yml
================================================
bugfixes:
- pfsense_rewrite_config - Drop obsolete and unneeded call to parse_config() (https://github.com/pfsensible/core/issues/239).
minor_changes:
- Add note to README about using pfsense_write_config to trigger XMLRPC configuration syncs (https://github.com/pfsensible/core/issues/239).
================================================
FILE: changelogs/fragments/242_gateway_loss.yml
================================================
minor_changes:
- pfsense_gateway - Add losshigh/losslow parameters (https://github.com/pfsensible/core/pull/242).
================================================
FILE: changelogs/fragments/243_openvpn_client.yml
================================================
bugfixes:
- pfsense_openvpn_client - Fix index calculation so that it actually updates the running client configuration (https://github.com/pfsensible/core/pull/243).
minor_changes:
- pfsense_openvpn_client - Return the vpnid (https://github.com/pfsensible/core/pull/243).
================================================
FILE: changelogs/fragments/245_arg_route.yaml
================================================
bugfixes:
- Fix initialization of arg_route (https://github.com/pfsensible/core/pull/245).
================================================
FILE: changelogs/fragments/248_class_level_imports.yaml
================================================
minor_changes:
- Remove class level imports in PFSenseModule to support the use of Mitogen (https://github.com/pfsensible/core/pull/248).
================================================
FILE: changelogs/fragments/251_setup_hardware.yaml
================================================
minor_changes:
- pfsense_setup - add crypto_hardware and thermal_hardware parameters (https://github.com/pfsensible/core/pull/251).
================================================
FILE: changelogs/fragments/rule_pass_before_deny_ordering.yml
================================================
bugfixes:
- pfsense_rule - New pass/match rules without explicit ``after`` or ``before`` are now inserted before the first block/reject rule on the same interface, preserving correct allow-before-deny ordering.
================================================
FILE: changelogs/fragments/rule_protocol_any_with_ports.yml
================================================
bugfixes:
- pfsense_rule - Allow protocol ``any`` with destination/source ports, matching pfSense UI behaviour.
================================================
FILE: examples/ipsec/README.md
================================================
# Managing ipsec tunnels with ansible-pfsense
This example will demonstrate how to manage your ipsec configuration.
It is designed for people who have multiple pfSense firewalls to setup.
## Description
We want to configure 3 firewalls and setup a fully connected VPN network between them.
We assume a standardized configuration (like each firewall uses it's wan interface),
done with ansible-pfsense indeed.
To easily acheive this goal, I have wrote an ansible filter. It takes a yaml file
for input, describing the desired VPNs properties, and generates output parameters
for the module [pfsense_ipsec_aggregate](https://github.com/opoplawski/ansible-pfsense/wiki/pfsense_ipsec_aggregate).
If you want to add new firewalls and networks to your topology, it only requires
a few more lines in the yaml definition file.
As far as possible, I tried to use the same parameters as for the ansible-pfsense
ipsec modules, in order to make writing the configuration yaml file more natural.
## Files
* ipsecs.yaml: the VPN properties
* hosts: the Ansible file for pfsense hosts
* setup_ipsec.yml: the playbook used to setup all the pfsenses
* filter_plugins/pfsense.py: the formatting plugin
* more.ipsecs.yaml: more VPN properties
## Installation
You don't need to copy any files. Just adapt your ansible hosts file like the one
provided or adapt the yaml file with your hosts.
To run the test in check mode for all the 3 firewalls, just go into your ansible-pfsense
directory and run:
```
ansible-playbook -C -v examples/ipsec/setup_ipsec.yml
```
## TODO
The filter plugin needs to be improved to support all kind of configuration
(especially regarding authentication parameters).
================================================
FILE: examples/ipsec/filter_plugins/pfsense.py
================================================
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.errors import AnsibleFilterError
def format_ipsec_aggregate_ipsecs(all_tunnels, pfname):
""" format ipsecs for format_ipsec_aggregate """
res = list()
for name, ipsec in all_tunnels.items():
pfsenses = ipsec['pfsenses']
if pfname not in pfsenses:
continue
local = pfsenses[pfname]
for remote_name, remote_options in pfsenses.items():
if remote_name == pfname:
continue
params = dict()
res.append(params)
params['descr'] = name + ' to ' + remote_name
params['state'] = 'present'
for option in ipsec:
if option in ['pfsenses', 'phase1', 'phase2']:
continue
params[option] = ipsec[option]
for option in remote_options:
if option in ['sharing', 'myid_data']:
continue
params[option] = remote_options[option]
if 'peerid_type' in params and params['peerid_type'] == 'keyid tag':
params['peerid_data'] = remote_options['myid_data']
if 'myid_data' in local:
params['myid_data'] = local['myid_data']
return res
def format_ipsec_aggregate_proposals(all_tunnels, pfname):
""" format proposals for format_ipsec_aggregate """
res = list()
for name, ipsec in all_tunnels.items():
pfsenses = ipsec['pfsenses']
if pfname not in pfsenses:
continue
if 'phase1' not in ipsec:
raise AnsibleFilterError("phase1 is missing in {0}".format(name))
phase1 = ipsec['phase1']
p1s = list()
if 'encryptions' not in phase1:
raise AnsibleFilterError("encryptions is missing in phase1 of {0}".format(name))
if 'hashes' not in phase1:
raise AnsibleFilterError("hashes is missing in phase1 of {0}".format(name))
encryptions = phase1['encryptions']
hashes = phase1['hashes'].split(' ')
for remote_name in pfsenses:
if remote_name == pfname:
continue
for encryption in encryptions:
for hash_option in hashes:
params = dict()
p1s.append(params)
params['descr'] = name + ' to ' + remote_name
params['state'] = 'present'
params['hash'] = hash_option
params['encryption'] = encryption
if encryptions[encryption] is not None and encryptions[encryption] != 'None':
params['key_length'] = encryptions[encryption]
for p1_option in phase1:
if p1_option in ['encryptions', 'hashes']:
continue
for p1 in p1s:
p1[p1_option] = phase1[p1_option]
res.extend(p1s)
return res
def format_ipsec_aggregate_p2s(all_tunnels, pfname):
""" format p2s for format_ipsec_aggregate """
res = list()
for name, ipsec in all_tunnels.items():
pfsenses = ipsec['pfsenses']
if pfname not in pfsenses:
continue
if 'phase2' not in ipsec:
raise AnsibleFilterError("phase2 is missing in {0}".format(name))
phase2 = ipsec['phase2']
if 'mode' not in phase2:
raise AnsibleFilterError("mode is missing in phase2 of {0}".format(name))
mode = phase2['mode']
local = pfsenses[pfname]
if 'sharing' in local:
local_sharing = local['sharing'].split(' ')
elif mode != 'transport':
raise AnsibleFilterError("sharing is missing for {0} in {1}".format(pfname, name))
p2s = list()
for remote_name, remote in pfsenses.items():
if remote_name == pfname:
continue
if 'sharing' in remote:
remote_sharing = remote['sharing'].split(' ')
elif mode != 'transport':
raise AnsibleFilterError("sharing is missing for {0} in {1}".format(remote_name, name))
if mode != 'transport':
for local_network in local_sharing:
for remote_network in remote_sharing:
params = dict()
p2s.append(params)
params['p1_descr'] = name + ' to ' + remote_name
params['descr'] = local_network + ' to ' + remote_network
params['state'] = 'present'
params['local'] = local_network
params['remote'] = remote_network
else:
params = dict()
p2s.append(params)
params['descr'] = name + ' to ' + remote_name
params['p1_descr'] = name + ' to ' + remote_name
params['state'] = 'present'
for p2_option, p2_value in phase2.items():
for p2 in p2s:
if p2_option == 'encryptions':
for encryption, keylength in p2_value.items():
p2[encryption] = True
if keylength is not None and keylength != 'None':
if isinstance(keylength, str):
p2[encryption + '_len'] = keylength
else:
p2[encryption + '_len'] = str(keylength)
elif p2_option == 'hashes':
hashes = p2_value.split(' ')
for hash_option in hashes:
p2[hash_option] = True
else:
p2[p2_option] = p2_value
res.extend(p2s)
return res
def format_ipsec_aggregate(*terms):
""" format var for ipsec_aggregate """
if len(terms) != 2 or not isinstance(terms[0], dict):
raise AnsibleFilterError("format_ipsec_aggregate expects one dictionnary of ipsec tunnels")
all_tunnels = terms[0]
pfname = terms[1]
res = dict()
res['aggregated_ipsecs'] = format_ipsec_aggregate_ipsecs(all_tunnels, pfname)
res['aggregated_ipsec_proposals'] = format_ipsec_aggregate_proposals(all_tunnels, pfname)
res['aggregated_ipsec_p2s'] = format_ipsec_aggregate_p2s(all_tunnels, pfname)
return res
class FilterModule(object):
""" FilterModule """
@staticmethod
def filters():
""" defined functions """
return {
'format_ipsec_aggregate': format_ipsec_aggregate,
}
================================================
FILE: examples/ipsec/hosts
================================================
[pfsense]
pf_1 ansible_ssh_host=10.0.1.1 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense
pf_2 ansible_ssh_host=10.0.2.1 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense
pf_3 ansible_ssh_host=10.0.3.1 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense
================================================
FILE: examples/ipsec/ipsecs.yaml
================================================
ipsec_tunnels:
fully_connected_vpn:
iketype: ikev2
interface: wan
myid_type: keyid tag
peerid_type: keyid tag
authentication_method: pre_shared_key
preshared_key: HHmWGzbeAtyE8f2E
lifetime: 43200
mode: main
pfsenses:
pf_1:
sharing: 192.168.1.0/24 172.16.1.0/24
remote_gateway: pf1.acme.com
myid_data: pf_1_id
pf_2:
sharing: 192.168.2.0/24 172.16.2.0/24
remote_gateway: pf2.acme.com
myid_data: pf_2_id
pf_3:
sharing: 192.168.3.0/24 172.16.3.0/24 10.3.3.0/24
remote_gateway: pf3.acme.com
myid_data: pf_3_id
phase1:
encryptions:
aes128gcm: 128
hashes: sha256
dhgroup: 14
phase2:
encryptions:
aes128gcm: 128
hashes: sha256
# misc
lifetime: 7200
pfsgroup: '14'
mode: tunnel
================================================
FILE: examples/ipsec/more.ipsecs.yaml
================================================
ipsec_tunnels:
fully_connected_vpn:
iketype: ikev2
interface: wan
myid_type: keyid tag
peerid_type: keyid tag
authentication_method: pre_shared_key
preshared_key: HHmWGzbeAtyE8f2E
lifetime: 43200
mode: main
pfsenses:
pf_1:
sharing: 192.168.1.0/24 172.16.1.0/24
remote_gateway: pf1.acme.com
myid_data: pf_1_id
pf_2:
sharing: 192.168.2.0/24 172.16.2.0/24
remote_gateway: pf2.acme.com
myid_data: pf_2_id
pf_3:
sharing: 192.168.3.0/24 172.16.3.0/24 10.3.3.0/24
remote_gateway: pf3.acme.com
myid_data: pf_3_id
phase1:
encryptions: { aes128gcm: 128, aes192gcm: 128, aes256gcm: 128, cast128: }
hashes: sha256 aesxcbc
dhgroup: 14
phase2:
encryptions: { aes128gcm: 128, aes192gcm: 128, aes256gcm: 128, cast128: None }
hashes: sha512 aesxcbc
# misc
lifetime: 7200
pfsgroup: '14'
mode: tunnel
================================================
FILE: examples/ipsec/setup_ipsec.yml
================================================
---
- hosts: pfsense
gather_facts: false
connection: paramiko
vars_files:
ipsecs.yaml
vars:
params: "{{ ipsec_tunnels|format_ipsec_aggregate(inventory_hostname) }}"
tasks:
- name: "setup ipsec"
pfsensible.core.pfsense_ipsec_aggregate:
purge_ipsecs: true
purge_ipsec_proposals: true
purge_ipsec_p2s: true
aggregated_ipsecs: "{{ params['aggregated_ipsecs'] }}"
aggregated_ipsec_proposals: "{{ params['aggregated_ipsec_proposals'] }}"
aggregated_ipsec_p2s: "{{ params['aggregated_ipsec_p2s'] }}"
================================================
FILE: examples/lookup/README.md
================================================
# Managing rules with lookup plugin
This example will demonstrate how to easily manage your rules configuration.
It is designed for people who have one to many pfSense firewalls to manage.
## General description
We want to configure multiple firewalls using only one set of pfSense, rules, and aliases.
Especially, we don't want to have to define several rules for each flow and firewall, when we have that kind of setup:
```
Host A <--> FW1 <--> ... <--> FW2 <--> Host B
```
If we want to allow Host A to connect to Host B, there should be only one definition of the flow for both firewalls.
We will write a file describing our network topology. The lookup plugin will parse that file and accordingly, will generate the required parameters for pfsense_aggregate to implement what is specified with that topology.
## Setup description
Let's say we have a network in Paris with:
```
- an internet router
- a pfSense (FW1) providing IPsec VTI connectivity to another office, in Fargo
- a laptop
- a station
- a DNS/proxy/ssh server
```
And in Fargo, there is:
```
- a pfSense (FW2), providing IPsec VTI connectivity to Paris
- a station
- some DNS servers
- access to other privates networks
```
Here are the rules we want to be defined on both FW1 and FW2:
```
- all icmp but icmp-redirect are allowed
- ospf is allowed on vti interfaces
- the Paris server must be able to do DNS requests to Fargo private DNS servers
- the Paris server can ssh into anything to Fargo office
- the Paris laptop can connect to anything to Fargo office
- the Fargo station must be able to connect to the Paris server on some ports (ssh, samba, squid, etc)
- the Fargo station can ssh into the Paris internet router
- the Fargo station can vnc into the Paris station
- the Fargo station can setup the Paris pfSense
```
## pfSenses definition
First, we will define our pfsenses:
```
pfsenses:
pf_fargo: {
interfaces: {
WAN: { remote_networks: internet },
LAN: { ip: 10.100.200.101/24 },
SERVERS: { ip: 192.168.1.101/24 },
IPsec: { ip: 10.9.8.2/30, remote_networks: paris_lan },
}
}
pf_paris: {
interfaces: {
LAN: { ip: 10.20.30.101/24, remote_networks: internet },
IPsec: { ip: 10.9.8.1/30, remote_networks: all_fargo_subnets },
}
}
```
### Fargo pfSense
On the Fargo pfSense, we are defining all networks used to access internet, the station, the servers and for the remote ipsec.
We need to specify an IP address for the IPsec interface, as we need rules for OSPF. We set the routed networks threw this interface to the Paris subnet
The pfSense name must match the name used in playbook.
### Paris pfSense
In this setup, as the pfSense is just an IPsec gateway there is no WAN interface.
The LAN interface is used to connect to internet.
We declare the Fargo subnets on the IPsec interface.
## Aliases definition
Now, we will define all the aliases we need:
```
hosts_aliases:
paris_lan: { ip: 10.20.30.0/24 }
paris_router: { ip: 10.20.30.1 }
paris_station: { ip: 10.20.30.2 }
paris_server: { ip: 10.20.30.3 }
paris_laptop: { ip: 10.20.30.4 }
paris_ssh_hosts: { ip: paris_server paris_router }
fargo_station: { ip: 10.100.200.10 }
fargo_ads: { ip: 192.168.1.1 192.168.1.2 192.168.1.3 }
all_fargo_subnets: { ip: 192.168.0.0/16 10.0.0.0/8 172.16.0.0/16 }
internet: { ip: 0.0.0.0/0 }
ipsec_vtis: { ip: 10.9.8.1 10.9.8.2 }
ports_aliases:
admin_ports: { port: 22 80 443 }
dns_port: { port: 53 }
ipsec_ports: { port: 500 4500 }
squid_port: { port: 3128 }
ssh_port: { port: 22 }
smb_ports: { port: 135 137 139 445 }
vnc_ports: { port: 5900-5901 }
```
## Rules definition
Finally, here are the rules:
```
rules:
options: { log: yes }
CONFIG:
config_from_lan: { src: paris_lan, dst: 10.20.30.101, protocol: tcp, dst_port: admin_ports }
ICMP:
block_redirects: { src: any, dst: any, protocol: icmp, icmptype: redir, action: block, log: yes }
allow_icmp: { src: any, dst: any, protocol: icmp, icmptype: any, log: no }
OSPF:
ospf_vtis: { src: ipsec_vtis, dst: ipsec_vtis, protocol: ospf, log: no }
FROM_FARGO:
config_from_fargo: { src: fargo_station, dst: 10.20.30.101, protocol: tcp, dst_port: admin_ports }
ssh_from_fargo: { src: fargo_station, dst: paris_ssh_hosts, protocol: tcp, dst_port: ssh_port }
proxy_from_fargo: { src: fargo_station, dst: paris_server, protocol: tcp, dst_port: squid_port }
smb_from_fargo: { src: fargo_station, dst: paris_server, protocol: tcp, dst_port: smb_ports }
vnc_from_fargo: { src: fargo_station, dst: paris_station, protocol: tcp, dst_port: vnc_ports }
TO_FARGO:
ssh_from_server: { src: paris_server, dst: all_fargo_subnets, protocol: tcp, dst_port: ssh_port }
dns_from_server: { src: paris_server, dst: fargo_ads, protocol: tcp/udp, dst_port: dns_port }
laptop_to_fargo: { src: paris_laptop, dst: all_fargo_subnets, protocol: any }
```
All the rules are logged, unless specified otherwise.
## Result:
All the required aliases and rules on each firewall are defined where they need to be.
### Fargo



### Paris



## Files
* hosts: the Ansible file for pfsense hosts
* pfsense_definitions.yaml: our rules & network topology
* setup_all_rules.yml: the playbook used to setup all the pfsenses
## Installation
You don't need to copy any files. Just adapt your ansible hosts file like the one
provided or adapt the yaml file with your hosts.
To run the test in check mode for all the 2 firewalls, just go into your ansible-pfsense
directory and run:
```
ansible-playbook -C -v examples/lookup/setup_all_rules.yml
```
You can run the plugin alone to see what is generated for the pfsense_aggregate module:
```
python ./lookup_plugins/pfsense.py examples/lookup/pfsense_definitions.yaml pf_paris
```
You can also add a rule name to just see what is generated for that rule:
```
python ./lookup_plugins/pfsense.py examples/lookup/pfsense_definitions.yaml pf_paris ssh_from_fargo
```
## TODO
The lookup plugin is still a work-in-progress. The code is quite ugly on some parts and it has a lot of limitations.
================================================
FILE: examples/lookup/hosts
================================================
[pfsense]
pf_paris ansible_ssh_host=10.20.30.101 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense
pf_fargo ansible_ssh_host=10.100.200.101 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense
================================================
FILE: examples/lookup/pfsense_definitions.yaml
================================================
---
#########################################################################################################################################
# P F S E N S E S #
#########################################################################################################################################
pfsenses:
pf_fargo: {
interfaces: {
WAN: { remote_networks: internet },
LAN: { ip: 10.100.200.101/24 },
SERVERS: { ip: 192.168.1.101/24 },
IPsec: { ip: 10.9.8.2/30, remote_networks: paris_lan },
}
}
pf_paris: {
interfaces: {
LAN: { ip: 10.20.30.101/24, remote_networks: internet },
IPsec: { ip: 10.9.8.1/30, remote_networks: all_fargo_subnets },
}
}
#########################################################################################################################################
# R U L E S #
#########################################################################################################################################
rules:
options: { log: yes }
CONFIG:
config_from_lan: { src: paris_lan, dst: 10.20.30.101, protocol: tcp, dst_port: admin_ports }
ICMP:
block_redirects: { src: any, dst: any, protocol: icmp, icmptype: redir, action: block, log: yes }
allow_icmp: { src: any, dst: any, protocol: icmp, icmptype: any, log: no }
OSPF:
ospf_vtis: { src: ipsec_vtis, dst: ipsec_vtis, protocol: ospf, log: no }
FROM_FARGO:
config_from_fargo: { src: fargo_station, dst: 10.20.30.101, protocol: tcp, dst_port: admin_ports }
ssh_from_fargo: { src: fargo_station, dst: paris_ssh_hosts, protocol: tcp, dst_port: ssh_port }
proxy_from_fargo: { src: fargo_station, dst: paris_server, protocol: tcp, dst_port: squid_port }
smb_from_fargo: { src: fargo_station, dst: paris_server, protocol: tcp, dst_port: smb_ports }
vnc_from_fargo: { src: fargo_station, dst: paris_station, protocol: tcp, dst_port: vnc_ports }
TO_FARGO:
ssh_from_server: { src: paris_server, dst: all_fargo_subnets, protocol: tcp, dst_port: ssh_port }
dns_from_server: { src: paris_server, dst: fargo_ads, protocol: tcp/udp, dst_port: dns_port }
laptop_to_fargo: { src: paris_laptop, dst: all_fargo_subnets, protocol: any }
#########################################################################################################################################
# A L I A S E S #
#########################################################################################################################################
hosts_aliases:
paris_lan: { ip: 10.20.30.0/24 }
paris_router: { ip: 10.20.30.1 }
paris_station: { ip: 10.20.30.2 }
paris_server: { ip: 10.20.30.3 }
paris_laptop: { ip: 10.20.30.4 }
paris_ssh_hosts: { ip: paris_server paris_router }
fargo_station: { ip: 10.100.200.10 }
fargo_ads: { ip: 192.168.1.1 192.168.1.2 192.168.1.3 }
all_fargo_subnets: { ip: 192.168.0.0/16 10.0.0.0/8 172.16.0.0/16 }
internet: { ip: 0.0.0.0/0 }
ipsec_vtis: { ip: 10.9.8.1 10.9.8.2 }
ports_aliases:
admin_ports: { port: 22 80 443 }
dns_port: { port: 53 }
ipsec_ports: { port: 500 4500 }
squid_port: { port: 3128 }
ssh_port: { port: 22 }
smb_ports: { port: 135 137 139 445 }
vnc_ports: { port: 5900-5901 }
================================================
FILE: examples/lookup/setup_all_rules.yml
================================================
---
- hosts: pfsense
gather_facts: true
connection: paramiko
vars:
params: "{{ lookup('pfsense', 'examples/lookup/pfsense_definitions.yaml', 'all_definitions') }}"
tasks:
- name: "setup aliases, rules & seperators"
pfsensible.core.pfsense_aggregate:
purge_rule_separators: true
purge_aliases: true
purge_rules: true
aggregated_aliases: "{{ params['aggregated_aliases'] }}"
aggregated_rules: "{{ params['aggregated_rules'] }}"
aggregated_rule_separators: "{{ params['aggregated_rule_separators'] }}"
================================================
FILE: examples/pfsense.yml
================================================
---
- hosts: pfsense
roles:
- pfsense
================================================
FILE: examples/pfsense_setup.yml
================================================
---
- hosts: pfsense
# For initial password connection use paramiko to handle BSD prompts
connection: paramiko
roles:
- pfsense_setup
================================================
FILE: examples/roles/pfsense/tasks/fail2ban.yml
================================================
---
- block:
- name: "Add fail2ban alias"
pfsensible.core.pfsense_alias:
name: fail2ban
type: urltable
address: http://127.0.0.1/aliastables/fail2ban
updatefreq: 128
descr: "For fail2ban"
detail: "updated by fail2ban"
state: present
- name: "Add fail2ban floating rules"
pfsensible.core.pfsense_rule:
name: "fail2ban dynamic block {{ item.name }}"
action: reject
interface: wan
floating: yes
ipprotocol: inet
protocol: any
direction: "{{ item.direction }}"
source: "{{ item.source }}"
destination: "{{ item.destination }}"
after: 'top'
state: present
loop:
- { name: incoming, direction: "in", source: fail2ban, destination: any }
- { name: outgoing, direction: "out", source: any, destination: fail2ban }
tags: pfsense-fail2ban
================================================
FILE: examples/roles/pfsense/tasks/main.yml
================================================
---
- block:
- name: "Add aliases"
pfsensible.core.pfsense_alias:
name: "{{ item.name }}"
type: "{{ item.type }}"
address: "{{ item.address }}"
descr: "{{ item.descr }}"
detail: "{{ item.detail }}"
state: present
loop:
- name: adservers
type: host
address: "172.16.10.10 172.16.10.11"
descr: "Active Directory Servers"
detail: "ad1||ad2"
- "{{ pfsense_aliases }}"
- name: "Set local network"
set_fact:
localnet: "{{ (ansible_igb0.ipv4[0].network ~ '/' ~ ansible_igb0.ipv4[0].netmask) | ipaddr('net') }}"
- name: "Add Internal traffic rules"
pfsensible.core.pfsense_rule:
name: "Allow Internal traffic to {{ item }}"
action: pass
interface: lan
ipprotocol: inet
protocol: any
source: "{{ localnet }}"
destination: "{{ item }}"
after: 'top'
state: present
loop:
- 10.0.0.0/8
- 192.168.0.0/16
- name: "Add Allow proxies out rule"
pfsensible.core.pfsense_rule:
name: 'Allow proxies out'
action: pass
interface: lan
ipprotocol: inet
protocol: tcp
source: webfilters
destination: any
after: 'Allow Internal traffic to 192.168.0.0/16'
state: present
- name: "Add Internal DNS out rule"
pfsensible.core.pfsense_rule:
name: 'Allow Internal DNS traffic out'
action: pass
interface: lan
ipprotocol: inet
protocol: udp
source: dns_int
destination: any:53
after: 'Allow proxies out'
state: present
- import_tasks: fail2ban.yml
tags: pfsense
================================================
FILE: examples/roles/pfsense_setup/tasks/main.yml
================================================
---
- block:
- name: "Load private data"
include_vars: keys.yml
# Different releases of pfSense work with different nss-pam-ldapd packages
- name: "Set facts"
set_fact:
nss_pam_ldap_pkg: http://pkg.freebsd.org/FreeBSD:11:amd64/release_2/All/nss-pam-ldapd-0.9.9.txz
when: ansible_distribution_version == "11.1"
- name: "Set facts"
set_fact:
nss_pam_ldap_pkg: http://pkg.freebsd.org/FreeBSD:11:amd64/latest/All/nss-pam-ldapd-0.9.10_1.txz
when: ansible_distribution_version == "11.2"
- name: "Install nss-pam-ldap"
# package:
# name: {{ nss_pam_ldap_pkg }}
# state: present
command: /usr/sbin/pkg add {{ nss_pam_ldap_pkg }}
register: pkg_command
changed_when: not pkg_command.stdout is search("is already installed")
- name: "Install packages"
package:
name: "{{ item }}"
state: present
loop:
- pfSense-pkg-sudo
# For pfsense ansible tasks
- py27-ipaddress
- name: "Configure nslcd"
template:
src: nslcd.conf.j2
dest: /usr/local/etc/nslcd.conf
mode: 0600
- name: "Install AD cert"
copy:
src: ad.example.com.crt
dest: /root/ad.example.com.crt
- name: "Configure /etc/nsswitch.conf"
lineinfile:
path: /etc/nsswitch.conf
regexp: "^({{ item }}):"
backrefs: yes
line: '\1: files ldap'
loop:
- group
- passwd
# Work around https://github.com/ansible/ansible/issues/41970
- name: "Enable nslcd in /etc/rc.conf.local"
lineinfile:
path: /etc/rc.conf.local
regexp: "^nslcd_enable=.*"
line: 'nslcd_enable="YES"'
create: yes
- name: "Enable and start nslcd"
service:
name: nslcd
enabled: true
state: started
- name: "Enable savehist"
lineinfile:
path: "/etc/skel/dot.tcshrc"
regexp: '^set savehist.*'
line: "set savehist='1024 merge'"
- name: "Setup admin users"
include_tasks: setup_user.yml
vars:
user: "{{ adminuser }}"
loop_control:
loop_var: adminuser
loop:
- "{{ admin_users }}"
tags: users
# Need to include sudoers.d in the GUI
- name: "Give Domain Admins sudo rights"
copy:
dest: /usr/local/etc/sudoers.d/admin
owner: root
group: wheel
mode: 0440
content: |
%Domain\ Admins ALL=(ALL) NOPASSWD: ALL
tags: pfsense_setup
================================================
FILE: examples/roles/pfsense_setup/tasks/setup_user.yml
================================================
---
- block:
- name: "Create home directory for {{ user }}"
file:
path: "/home/{{ user }}"
owner: "{{ user }}"
group: "{{ user }}"
mode: 0750
state: directory
- name: "Create .ssh directory"
file:
path: "/home/{{ user }}/.ssh"
owner: "{{ user }}"
group: "{{ user }}"
mode: 0700
state: directory
- name: "Install {{ item }}"
copy:
dest: "/home/{{ user }}/{{ item }}"
src: /etc/skel/dot{{ item }}
remote_src: yes
owner: "{{ user }}"
group: "{{ user }}"
loop:
- .hushlogin
- .tcshrc
- name: "Install authorized_keys for {{ user }}"
copy:
dest: "/home/{{ user }}/.ssh/authorized_keys"
owner: "{{ user }}"
group: "{{ user }}"
mode: 0600
content: "{% for pub_key in ssh_pub_key[user] %}{{ pub_key }}\n{% endfor %}"
tags: users
================================================
FILE: examples/roles/pfsense_setup/templates/nslcd.conf.j2
================================================
# This is the configuration file for the LDAP nameservice
# switch library's nslcd daemon. It configures the mapping
# between NSS names (see /etc/nsswitch.conf) and LDAP
# information in the directory.
# See the manual page nslcd.conf(5) for more information.
# The user and group nslcd should run as.
uid nslcd
gid nslcd
# The uri pointing to the LDAP server to use for name lookups.
# Multiple entries may be specified. The address that is used
# here should be resolvable without using LDAP (obviously).
#uri ldap://127.0.0.1/
#uri ldaps://127.0.0.1/
#uri ldapi://%2fvar%2frun%2fldapi_sock/
# Note: %2f encodes the '/' used as directory separator
{% for server in adservers %}
uri ldaps://{{ server }}/
{% endfor %}
# The LDAP version to use (defaults to 3
# if supported by client library)
#ldap_version 3
# The distinguished name of the search base.
base dc=example,dc=com
# The distinguished name to bind to the server with.
# Optional: default is to bind anonymously.
binddn {{ ad_bind_user }}
# The credentials to bind with.
# Optional: default is no credentials.
# Note that if you set a bindpw you should check the permissions of this file.
bindpw {{ ad_bind_password }}
# The distinguished name to perform password modifications by root by.
#rootpwmoddn cn=admin,dc=example,dc=com
# The default search scope.
scope sub
#scope one
#scope base
# Customize certain database lookups.
#base group ou=Groups,dc=example,dc=com
#base passwd ou=People,dc=example,dc=com
#base shadow ou=People,dc=example,dc=com
#scope group onelevel
#scope hosts sub
# Bind/connect timelimit.
#bind_timelimit 30
# Search timelimit.
#timelimit 30
# Idle timelimit. nslcd will close connections if the
# server has not been contacted for the number of seconds.
#idle_timelimit 3600
# Use StartTLS without verifying the server certificate.
#ssl start_tls
#tls_reqcert never
# CA certificates for server certificate verification
#tls_cacertdir /etc/ssl/certs
tls_cacertfile /root/ad.crt
# Seed the PRNG if /dev/urandom is not provided
#tls_randfile /var/run/egd-pool
# SSL cipher suite
# See man ciphers for syntax
#tls_ciphers TLSv1
# Client certificate and key
# Use these, if your server requires client authentication.
#tls_cert
#tls_key
# Mappings for Services for UNIX 3.5
#filter passwd (objectClass=User)
#map passwd uid msSFU30Name
#map passwd userPassword msSFU30Password
#map passwd homeDirectory msSFU30HomeDirectory
#map passwd homeDirectory msSFUHomeDirectory
#filter shadow (objectClass=User)
#map shadow uid msSFU30Name
#map shadow userPassword msSFU30Password
#filter group (objectClass=Group)
#map group member msSFU30PosixMember
# Mappings for Services for UNIX 2.0
#filter passwd (objectClass=User)
#map passwd uid msSFUName
#map passwd userPassword msSFUPassword
#map passwd homeDirectory msSFUHomeDirectory
#map passwd gecos msSFUName
#filter shadow (objectClass=User)
#map shadow uid msSFUName
#map shadow userPassword msSFUPassword
#map shadow shadowLastChange pwdLastSet
#filter group (objectClass=Group)
#map group member posixMember
# Mappings for Active Directory
#pagesize 1000
#referrals off
#idle_timelimit 800
#filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*))
#map passwd uid sAMAccountName
#map passwd homeDirectory unixHomeDirectory
#map passwd gecos displayName
#filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*))
#map shadow uid sAMAccountName
#map shadow shadowLastChange pwdLastSet
#filter group (objectClass=group)
# Alternative mappings for Active Directory
# (replace the SIDs in the objectSid mappings with the value for your domain)
pagesize 1000
referrals off
idle_timelimit 800
filter passwd (&(objectClass=user)(objectClass=person)(!(objectClass=computer)))
map passwd uid sAMAccountName
map passwd uidNumber objectSid:S-1-5-21-89655523-1570529619-2103694531
map passwd gidNumber objectSid:S-1-5-21-89655523-1570529619-2103694531
map passwd homeDirectory "/home/$sAMAccountName"
map passwd gecos displayName
map passwd loginShell "/bin/sh"
filter group (|(objectClass=group)(objectClass=person))
map group cn sAMAccountName
map group gidNumber objectSid:S-1-5-21-89655523-1570529619-2103694531
# Mappings for AIX SecureWay
#filter passwd (objectClass=aixAccount)
#map passwd uid userName
#map passwd userPassword passwordChar
#map passwd uidNumber uid
#map passwd gidNumber gid
#filter group (objectClass=aixAccessGroup)
#map group cn groupName
#map group gidNumber gid
================================================
FILE: galaxy.yml
================================================
### REQUIRED
# The namespace of the collection. This can be a company/brand/organization or product namespace under which all
# content lives. May only contain alphanumeric characters and underscores. Additionally namespaces cannot start with
# underscores or numbers and cannot contain consecutive underscores
namespace: pfsensible
# The name of the collection. Has the same character restrictions as 'namespace'
name: core
# The version of the collection. Must be compatible with semantic versioning
version: 0.7.2
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
# A list of the collection's content authors. Can be just the name or in the format 'Full Name <email> (url)
# @nicks:irc/im.site#channel'
authors:
- Orion Poplawski
- Frederic Bor
- taylor vories
- Jan Wenzel
### OPTIONAL but strongly recommended
# A short summary description of the collection
description: Core modules for managing pfSense
# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only
# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file'
license:
- GPL-3.0-or-later
# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character
# requirements as 'namespace' and 'name'
tags:
- networking
- pfsense
# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
# collection label 'namespace.name'. The value is a version range
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
# range specifiers can be set and are separated by ','
dependencies: {}
# The URL of the originating SCM repository
repository: https://github.com/pfsensible/core
# The URL to any online docs
documentation: https://github.com/pfsensible/core/wiki
# The URL to the homepage of the collection/project
homepage: https://github.com/pfsensible/core
# The URL to the collection issue tracker
issues: https://github.com/pfsensible/core/issues
build_ignore:
- .github
- .gitignore
- .travis.yml
- '*.tar.gz'
- changelogs
- examples
- misc
- setup.cfg
================================================
FILE: meta/runtime.yml
================================================
plugin_routing:
modules:
pfsense_haproxy_backend:
deprecation:
removal_version: 0.8.0
warning_text: Use pfsensible.haproxy.pfsense_haproxy_backend instead.
pfsense_haproxy_backend_server:
deprecation:
removal_version: 0.8.0
warning_text: Use pfsensible.haproxy.pfsense_haproxy_backend_server instead.
requires_ansible: ">=2.12"
================================================
FILE: misc/.coveragerc
================================================
[run]
include = *pfsense*
================================================
FILE: misc/ansible2local
================================================
#!/bin/sh
if [ -z "${ANSIBLE_HOME}" ]
then
echo "ANSIBLE_HOME is undefined. Go into ansible directory and run 'source hacking/env-setup'"
exit 1
fi
cp ${ANSIBLE_HOME}/test/units/modules/network/pfsense/*.py test/units/modules/network/pfsense/
cp ${ANSIBLE_HOME}/test/units/modules/network/pfsense/fixtures/*.xml test/units/modules/network/pfsense/fixtures/
cp ${ANSIBLE_HOME}/lib/ansible/module_utils/network/pfsense/*.py module_utils/network/pfsense/
cp ${ANSIBLE_HOME}/lib/ansible/modules/network/pfsense/*.py library/
cp ${ANSIBLE_HOME}/lib/ansible/plugins/lookup/pfsense.py lookup_plugins/pfsense.py
================================================
FILE: misc/local2ansible
================================================
#!/bin/sh
if [ -z "${ANSIBLE_HOME}" ]
then
ANSIBLE_INSTALL=`ansible --version 2> /dev/null | grep 'module location' | cut -d '=' -f 2 | sed -e s/^[[:space:]]*//`
if [ -z "$ANSIBLE_INSTALL" ]
then
echo "ANSIBLE_HOME is undefined and ansible is not found. Install ansible or go into ansible source directory and run 'source hacking/env-setup'"
exit 1
fi
echo Installing into program dir: ${ANSIBLE_INSTALL}
else
ANSIBLE_INSTALL=${ANSIBLE_HOME}/lib/ansible
echo Installing into source dir: ${ANSIBLE_INSTALL}
# tests are installed in source dir only
mkdir -p ${ANSIBLE_HOME}/test/units/modules/network/pfsense/fixtures
cp test/units/modules/network/pfsense/*.py ${ANSIBLE_HOME}/test/units/modules/network/pfsense/
cp -rp test/units/modules/network/pfsense/fixtures/* ${ANSIBLE_HOME}/test/units/modules/network/pfsense/fixtures/
cp test/units/plugins/lookup/*.py ${ANSIBLE_HOME}/test/units/plugins/lookup/
# cp test/units/plugins/lookup/fixtures/*.yaml ${ANSIBLE_HOME}/test/units/plugins/lookup/fixtures/
fi
mkdir -p ${ANSIBLE_INSTALL}/module_utils/network/pfsense
mkdir -p ${ANSIBLE_INSTALL}/modules/network/pfsense
# remove old modules imports
rm -rf ${ANSIBLE_INSTALL}/module_utils/network/pfsense/pfense_*
cp module_utils/network/pfsense/*.py ${ANSIBLE_INSTALL}/module_utils/network/pfsense/
cp library/*.py ${ANSIBLE_INSTALL}/modules/network/pfsense/
cp lookup_plugins/pfsense.py ${ANSIBLE_INSTALL}/plugins/lookup/pfsense.py
touch ${ANSIBLE_INSTALL}/module_utils/network/__init__.py
touch ${ANSIBLE_INSTALL}/modules/network/__init__.py
touch ${ANSIBLE_INSTALL}/modules/network/pfsense/__init__.py
================================================
FILE: misc/mkpfcollection
================================================
#!/bin/bash -eux
mkdir -p {examples,misc,plugins,tests/unit}
git mv library/* plugins/modules/
rmdir library
git mv module_utils/network/pfsense plugins/module_utils
git rm -r module_utils
rm -rf module_utils
git mv {pfsense.yml,pfsense_setup.yml,roles} examples/
git mv lookup_plugins plugins/lookup/
git mv test/units/plugins tests/unit/
mkdir tests/unit/plugins/modules
git mv test/units/modules/network/pfsense/* tests/unit/plugins/modules/
git rm -r test
rm -r test
sed -i -e 's/pfsense_\([a-z]\)/pfsensible.core.pfsense_\1/g' -e s,opoplawski/ansible-pfsense,pfsensible/core, README.md
sed -i -e 's/\(pfsense_.*:\)/pfsensible.core.\1/g' $(find examples -name \*.yml)
sed -i -e s/ansible.modules.network.pfsense/ansible_collections.pfsensible.core.plugins.modules/ \
-e s/ansible.plugins.lookup.pfsense/ansible_collections.pfsensible.core.plugins.lookup.pfsense/ \
-e "s/lookup_loader.get('pfsense')/lookup_loader.get('pfsensible.core.pfsense')/" \
-e s/ansible.module_utils.network.pfsense/ansible_collections.pfsensible.core.plugins.module_utils/ \
-e s/ansible.module_utils.compat/ansible_collections.ansible.netcommon.plugins.module_utils.compat/ \
-e s/units.compat.mock/ansible_collections.community.internal_test_tools.tests.unit.compat.mock/ \
-e s/ansible.module_utils.compat.ipaddress/ansible_collections.pfsensible.core.plugins.module_utils.compat.ipaddress/ \
-e s/units.modules.utils/ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils/ \
-e '/version_added/s/"2.10"/0.1.0/' \
$(find -name \*.py)
rm -f pfsensible-core-*.tar.gz
ansible-galaxy collection build
================================================
FILE: misc/mkpfsensible
================================================
#!/bin/bash -eu
[ ! -d ansible-pfsense ] && echo "No such directory ansible-pfsense" && exit 1
[ ! -d pfsensible/core ] && echo "No such directory pfsensible/core" && exit 1
rm -rf pfsensible/core/{examples,misc,plugins,tests/units/modules,*.tar.gz}
mkdir -p pfsensible/core/{examples,misc,plugins/modules,tests/units/modules}
cp -a ansible-pfsense/{.gitignore,examples,LICENSE} pfsensible/core/
cp -a ansible-pfsense/{pfsense.yml,pfsense_setup.yml,roles} pfsensible/core/examples/
cp -a ansible-pfsense/lookup_plugins pfsensible/core/plugins/lookup
cp -a ansible-pfsense/module_utils/network/pfsense pfsensible/core/plugins/module_utils
cp -a ansible-pfsense/test/units/modules/network/pfsense/* pfsensible/core/tests/units/modules/
for path in ansible-pfsense/library/*.py
do
filename=${path##*/}
cp -a $path pfsensible/core/plugins/modules/${filename/pfsense_/}
done
sed -i -e 's/\(pfsense_.*:\)/pfsensible.core.\1/g' $(find pfsensible/core/examples -name \*.yml)
sed -i -e '/import\|module:\|^ *pfsense_[a-z_0-9]*:$\|descr *= *.ansible pfsense_/s/pfsense_/pfsensible.core.pfsense_/' $(find pfsensible/core/plugins/modules -name \*.py)
sed -i -e '/self.name = /s/pfsense_/pfsensible.core.pfsense_/' $(find pfsensible/core -name \*.py)
sed -i -e s/ansible.module_utils.network.pfsense/ansible_collections.pfsensible.core.plugins.module_utils/ $(find pfsensible -name \*.py)
sed -i -e 's/ansible.modules.network.pfsense import pfsense_/ansible_collections.pfsensible.core import /' $(find pfsensible/core/tests -name \*.py)
cd pfsensible/core
ansible-galaxy collection build
================================================
FILE: misc/pfsense_module.py.j2
================================================
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) {{ year }}, {{ author_name }} <{{ author_email }}>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
---
module: pfsense_{{ module_name }}
short_description: Manage pfSense {{ module_name }}{{ ' configuration' if is_config else 's' }}
version_added: "0.7.0"
description:
- Manage pfSense {{ module_name }}{{ ' configuration' if is_config else 's' }}.{{ ' This requires the pfSense ' ~ package ~ ' package to be installed.' if package != 'core' else '' }}
options:
{% if not is_config %}
{{ name_param }}:
description: The {{ name_param }} of the {{ module_name }}.
required: true
type: str
state:
description: State in which to leave the {{ module_name }}.
default: present
choices: ['present', 'absent']
type: str
{% endif %}
{% for name, param in params.items() %}
{{ name }}:
description: {{ "'" if ':' in param['description'] else '' }}{{ param['description'] | default('') }}{{ "'" if ':' in param['description'] else '' }}
{% if 'default' in param and not is_config %}
default: {{ param['default'] }}
{% endif %}
{% if 'choices' in param %}
choices: {{ param['choices'] }}
{% endif %}
type: {{ param['type'] | default('') }}
{% if param['type'] == 'list' %}
elements: {{ param['elements'] | default('str') }}
{% endif %}
{% endfor %}
author: {{ author_name }} (@{{ author_handle }})
'''
EXAMPLES = r'''
- name: {{ 'Configure' if is_config else 'Add myitem' }} {{ module_name }}
pfsensible.{{ package | lower() }}.pfsense_{{ module_name }}:
{% if not is_config %}
{{ name_param }}: myitem
{% endif %}
{% for name, param in params.items() %}
{% if param['example'] is defined %}
{% if param['type'] == 'list' %}
{{ name }}:
- {{ param['example'] }}
- {{ param['example2'] | default('another item') }}
{% else %}
{{ name }}: {{ param['example'] }}
{% endif %}
{% else %}
{{ name }}: {% if param['type'] == 'bool' %}false{% elif param['type'] == 'list' %}{% if 'choices' in param %}['{{ param['choices'][0:1] | join("', '") }}']{% else %}['item']{% endif %}{% elif param['type'] == 'str' %}{{ param['choices'][0] if 'choices' in param else '' }}{% endif %}
{% endif %}
{% endfor %}
{% if not is_config %}
state: present
- name: Remove myitem {{ module_name }}
pfsensible.{{ package | lower() }}.pfsense_{{ module_name }}:
{{ name_param }}: myitem
state: absent
{% endif %}
'''
RETURN = r'''
commands:
description: the set of commands that would be pushed to the remote device (if pfSense had a CLI).
returned: always
type: list
{% if is_config %}
sample: ["update {{ module_name }} set ..."]
{% else %}
sample: ["create {{ module_name }} 'myitem'", "update {{ module_name }} 'myitem' set ...", "delete {{ module_name }} 'myitem'"]
{% endif %}
'''
from ansible.module_utils.basic import AnsibleModule
{% if is_config %}
from ansible_collections.pfsensible.core.plugins.module_utils.module_config_base import PFSenseModuleConfigBase
{% else %}
from ansible_collections.pfsensible.core.plugins.module_utils.module_base import PFSenseModuleBase
{% endif %}
{% if args_imports %}
from ansible_collections.pfsensible.core.plugins.module_utils.arg_route import {{ args_imports | sort | join(', ') }}
{% endif %}
# TODO - Keep either this or the next compact version of {{ module_name | upper() }}_ARGUMENT_SPEC
{{ module_name | upper() }}_ARGUMENT_SPEC = {
{% if not is_config %}
# Only {{ name_param }} should be required here - othewise you cannot remove an item with just '{{ name_param }}'
# Required arguments for creation should be noted in {{ module_name | upper() }}_REQUIRED_IF = ['state', 'present', ...] below
'{{ name_param }}': {'required': True, 'type': 'str'},
'state': {
'type': 'str',
'default': 'present',
'choices': ['present', 'absent']
},
{% endif %}
{% for param in params %}
'{{ param }}': {
{% if 'choices' in params[param] %}
'choices': {{ params[param]['choices'] }},
{% endif %}
{% if 'default' in params[param] %}
'default': '{{ params[param]['default'] }}',
{% endif %}
'type': '{{ params[param]['type'] | default('') }}',
},
{% endfor %}
}
# Compact style
{{ module_name | upper() }}_ARGUMENT_SPEC = dict(
{% if not is_config %}
# Only {{ name_param }} should be required here - othewise you cannot remove an item with just '{{ name_param }}'
# Required arguments for creation should be noted in {{ module_name | upper() }}_REQUIRED_IF = ['state', 'present', ...] below
{{ name_param }}=dict(required=True, type='str'),
state=dict(type='str', default='present', choices=['present', 'absent']),
{% endif %}
{% for param in params %}
{{ param }}=dict(type='{{ params[param]['type'] | default('') }}'{% if 'choices' in params[param] %}, choices={{ params[param]['choices'] }}{% endif %}{% if 'default' in params[param] and not is_config %}, default='{{ params[param]['default'] }}'{% endif %}),
{% endfor %}
)
# TODO - Check for validity - what parameters are actually required when creating a new {{ module_name }}?
{{ module_name | upper() }}_REQUIRED_IF = [
{% if not is_config %}
{% if module_type %}
['state', 'present', ['type']],
['type', '{{ params['type']['example'] }}', ['{{ params | dict2items | rejectattr('key', 'equalto', 'type') | selectattr('value.required', 'defined') | rejectattr('value.default', 'defined') | map(attribute='key') | join("', '") }}']],
{% else %}
['state', 'present', ['{{ params | dict2items | selectattr('value.required', 'defined') | rejectattr('value.default', 'defined') | map(attribute='key') | join("', '") }}']],
{% endif %}
{% endif %}
]
{% if params_xml_only %}
# TODO - Check this for validity and matching module argument
{{ module_name | upper() }}_MAP_PARAM = [
{% for param in params_xml_only %}
('ARG', '{{ param }}'),
{% endfor %}
]
{% endif %}
# TODO - Review this for clues for input validation. Search for functions in the below require_once files in /etc and /usr/local/pfSense/include
PHP_VALIDATION = r'''
{{ php_requires }}
{{ php_save }}
'''
# TODO - Add validation and parsing methods for parameters that require it
{{ module_name | upper() }}_ARG_ROUTE = dict(
{% set param_items = ((params | dict2items | selectattr('value.parse', 'defined') | list) + (params | dict2items | selectattr('value.validate', 'defined')) | list) | unique %}
{% if param_items %}
{% for param_item in param_items %}
{{ param_item.key }}=dict({% if param_item.value.parse is defined %}parse={{ param_item.value.parse }},{% endif %}{% if param_item.value.validate is defined %}validate={{ param_item.value.validate }},{% endif %}),
{% endfor %}
{% else %}
# TODO - These are just examples
authorizedkeys=dict(parse=p2o_ssh_pub_key),
password=dict(validate=validate_password),
{% endif %}
)
{% if bool_values == 'inconsistent' %}
{{ module_name | upper() }}_BOOL_VALUES = dict(
{% for k, v in bool_values.items() %}
{{ k }}=(None, "{{ v }}"),
{% endfor %}
)
{% endif %}
# TODO - Check for validity - what are default values when creating a new {{ module_name }}
{{ module_name | upper() }}_CREATE_DEFAULT = dict(
{% for item in params | dict2items | selectattr('value.default', 'defined') %}
{{ item.key }}='{{ item.value.default | default('VALUE') }}',
{% endfor %}
{% for param in params_xml_only %}
{{ param }}='{{ params[param]['example'] | default('VALUE') }}',
{% endfor %}
)
{% if package != 'core' %}
{{ module_name | upper() }}_PHP_COMMAND_SET = r'''
require_once("{{ package | lower() }}.inc");
{{ package | lower() }}_sync_package();
'''
{% elif 'filter.inc' in php_requires %}
{{ module_name | upper() }}_PHP_COMMAND_SET = r'''
require_once("filter.inc");
if (filter_configure() == 0) { clear_subsystem_dirty('{{ php_subsystem }}'); }
'''
{% endif %}
class {{ pfsense_module_name }}({{ module_base }}):
""" module managing pfsense {{ module_name }}{{ ' configuration' if is_config else 's' }} """
##############################
# unit tests
#
# Must be class method for unit test usage
@staticmethod
def get_argument_spec():
""" return argument spec """
return {{ module_name | upper() }}_ARGUMENT_SPEC
def __init__(self, module, pfsense=None):
super({{ pfsense_module_name }}, self).__init__(module, pfsense, {{ 'package=\'' ~ package ~ '\', ' if package != 'core' else ''}}root='{{ module_root }}', node='{{ module_node }}', key='{{ module_key }}'{{ ', update_php=' ~ module_name | upper() ~ '_PHP_COMMAND_SET' if 'filter.inc' in php_requires else '' }},
arg_route={{ module_name | upper() }}_ARG_ROUTE{% if bool_style != 'inconsistent' %}, bool_style="{{ bool_style }}"{% else %}, bool_values={{ module_name | upper() }}_BOOL_VALUES{% endif %}{% if params_xml_only %}, map_param={{ module_name | upper() }}_MAP_PARAM{% endif %}, create_default={{ module_name | upper() }}_CREATE_DEFAULT)
{% if package != 'core' %}
##############################
# run
#
# TODO - find the correct sync function
def _update(self):
""" make the target pfsense reload """
return self.pfsense.phpshell({{ module_name | upper() }}_PHP_COMMAND_SET)
{% endif %}
{% if is_config %}
##############################
# Logging
#
@staticmethod
def _get_obj_name():
""" return obj's name """
return "{{ module_name }}"
{% endif %}
def main():
module = AnsibleModule(
argument_spec={{ module_name | upper() }}_ARGUMENT_SPEC,
required_if={{ module_name | upper() }}_REQUIRED_IF,
supports_check_mode=True)
pfmodule = {{ pfsense_module_name }}(module)
# Pass params for testing framework
pfmodule.run(module.params)
pfmodule.commit_changes()
if __name__ == '__main__':
main()
================================================
FILE: misc/pfsensible-generate-module
================================================
#!/usr/bin/python3
# Copyright: (c) 2024, Orion Poplawski <orion@nwra.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# TODO:
# - validation for addresses
# - bool type determination and parameter list
# - generate version_added
# - detect packages
from ansible.plugins.filter.core import dict_to_list_of_dict_key_value_elements
from ansible.plugins.filter.mathstuff import unique
import argparse
import datetime
import getpass
import git
import jinja2
import lxml.etree as ET
import lxml.html
import os
from paramiko import SSHClient
import re
import requests
from scp import SCPClient, SCPException
import shutil
import sys
import tempfile
from urllib.parse import urlparse
gitconfig = git.GitConfigParser()
author_name = gitconfig.get_value('user', 'name')
author_email = gitconfig.get_value('user', 'email')
package = 'core'
module_base = 'PFSenseModuleBase'
module_key = None
module_node = None
name_param = None
params_xml_only = []
is_simple_package = False
is_full_package = False
args_imports = []
php_requires = ''
php_save = ''
php_subsystem = ''
parser = argparse.ArgumentParser(description='Generate a pfsensible module.')
parser.add_argument('--url', help='The URL to scrape')
parser.add_argument('--urlfile', help='A local file copy of the URL to scrape')
parser.add_argument('--user', default='admin', help='The user to connect to the web interface as (defaults to "admin")')
parser.add_argument('--password', default='pfsense', help='The password of user')
parser.add_argument('--password-prompt', action='store_true', help='Prompt for the password of user')
parser.add_argument('--ssh-no-agent', action='store_true', help='Do not use ssh agent for connection')
parser.add_argument('--ssh-user', default='root', help='The user to connect via ssh as (defaults to "root")')
parser.add_argument('--ssh-password', default='pfsense', help='The password of the ssh user')
parser.add_argument('--ssh-password-prompt', action='store_true', help='Prompt for the password of the ssh user')
parser.add_argument('--author-name', default=author_name, help='The full name of the module author')
parser.add_argument('--author-email', default=author_email, help='The email address of the module author')
parser.add_argument('--author-handle', default='', help='The github handle of the module author')
parser.add_argument('--module-name', help='The name of the module to generate - defaults to being based on the url, required with --urlfile')
parser.add_argument('--is-config', action='store_true', help='This is a configuration module', )
parser.add_argument('--name-param', help='The name of the primary module parameter - defaults to the key, but often "name" is used instead of "descr"')
parser.add_argument('--type-param', default='type', help='The name of the parameter for selecting different types of elements', )
parser.add_argument('--type-suffix', const=True, default=False, nargs='?', help='Suffix the module name with the item type', )
parser.add_argument('--root-elt', default='root', help='The xml config element to find items under')
parser.add_argument('--item-min', default='item_min', help='The name of the minimally configured item to search for in config.xml (defaults to "item_min")')
parser.add_argument('--item-full', default='item_full',
help='The name of the fully configured item to search for in config.xml, will be used for exmaples in the documentation (defaults to "item_max")')
parser.add_argument('--host', help='The name of the pfsense host to connect to - only used with --urlfile')
parser.add_argument('--force', action=argparse.BooleanOptionalAction, help='Force overwriting the output file if it exists')
parser.add_argument('--keep-tmpdir', action=argparse.BooleanOptionalAction, help='Keep the downloaded files in the temporary directory')
parser.add_argument('--keep-params', action=argparse.BooleanOptionalAction, help='Keep parameters from the web interface not found in the XML')
parser.add_argument('--verbose', '-v', action='count', default=0)
args = parser.parse_args()
# TODO - require a --module-root arg or search for it
if args.is_config:
module_root = 'system'
# Temporary directory for files
tmpdir = tempfile.TemporaryDirectory(prefix='pfgenmod-')
if args.url is not None:
uri = urlparse(args.url)
# Login using just the base URL
login_url = f'{uri.scheme}://{uri.netloc}/'
# Collect host for later use to scp config.xml
host = f'{uri.netloc}'
# Collect phpfile to scp later
phpfile = re.sub(r'^.*/([^/]+\.php).*$', r'\1', uri.path)
# Construct a likely module name from the URL
if args.module_name is None:
# See if this pkg_edit URL first
if re.match(r'/pkg', uri.path):
module_name = re.sub(r'^xml=.*?([^/]+)\.xml.*$', r'\1', uri.query)
package = re.sub(r'([^_]+).*', r'\1', module_name)
is_simple_package = True
phpfile = None
elif (match := re.match(r'/([^/]+)/([^_]+_.+)\.php', uri.path)) is not None:
module_name = re.sub(r'(?:_edit|manager)$', '', match.group(2))
package = match.group(1)
is_full_package = True
else:
module_name = re.sub(r'^/(?:firewall_|services_|system_)?(.*?)(?:_edit|manager)?\.php$', r'\1', uri.path)
module_name_singular = re.sub(r'ses$', 's', module_name)
if module_name_singular != module_name:
module_name = module_name_singular
else:
module_name = re.sub(r's$', '', module_name)
else:
module_name = args.module_name
# We likely don't have a valid certificate
requests.packages.urllib3.disable_warnings()
# Start our session (need cookies for login)
client = requests.Session()
# Retrieve the CSRF token first
try:
r = client.get(login_url, verify=False)
except requests.exceptions.ConnectionError as e:
print(f'Failed to connect to {login_url}: {e}', file=sys.stderr)
sys.exit(1)
csrf = re.search(".*name='__csrf_magic' value=\"([^\"]+)\".*", r.text, flags=re.MULTILINE).group(1)
# Prompt for web password if requested
if args.password_prompt:
args.password = getpass.getpass("Enter your web user password: ")
# Login to the web interface
login_data = dict(login='Login', usernamefld=args.user, passwordfld=args.password, __csrf_magic=csrf)
r = client.post(login_url, data=login_data, verify=False)
if (args.verbose >= 4):
print(f'Login URL returned {r} {r.text}')
html = lxml.html.fromstring(r.text)
# <div class="col-sm-4 nowarning msgbox text-center text-danger"><h4>Username or Password incorrect</h4></div>
alert = html.xpath('//div[contains(@class,"text-danger")]/*[1]/text()')
if len(alert) > 0:
print(f'Login failed with "{alert[0]}"', file=sys.stderr)
sys.exit(1)
# Retrieve the configuration web page and parse it
r = client.get(args.url, verify=False)
if (args.verbose >= 4):
print(f'{args.url} returned {r} {r.text}')
html = lxml.html.fromstring(r.text)
elif args.urlfile is not None:
# Use a cached copy of the web page - get rid of this? Need to specify host and module name
html = lxml.html.parse(args.urlfile)
host = args.host
module_name = args.module_name
else:
sys.exit('You must specify one of --url or --urlfile')
# Prompt for ssh password if requested
if args.ssh_password_prompt:
args.ssh_password = getpass.getpass("Enter your ssh user password: ")
# Collect the /cf/conf/config.xml file
with SSHClient() as ssh:
ssh.load_system_host_keys()
ssh.connect(host, username=args.ssh_user, allow_agent=not args.ssh_no_agent, password=args.ssh_password)
files_to_sftp = ['/cf/conf/config.xml']
if is_simple_package:
files_to_sftp.append(f'/usr/local/pkg/{package}.inc')
files_to_sftp.append(f'/usr/local/pkg/inc/{package}.inc')
files_to_sftp.append(f'/usr/local/pkg/{package}.xml')
elif is_full_package:
files_to_sftp.append(f'/usr/local/www/{package}/{phpfile}')
files_to_sftp.append(f'/usr/local/pkg/{package}/{package}.inc')
files_to_sftp.append(f'/usr/local/pkg/{package}.xml')
elif phpfile is not None:
files_to_sftp.append(f'/usr/local/www/{phpfile}')
with ssh.open_sftp() as sftp:
for file in files_to_sftp:
try:
if (args.verbose >= 1):
print(f'Copying {file}')
sftp.get(file, f'{tmpdir.name}/{os.path.basename(file)}')
except FileNotFoundError as e:
pass
# Save the scraped web page if asked to keep files
if args.keep_tmpdir:
f = open(f'{tmpdir.name}/{module_name}.html', 'w')
f.write(r.text)
f.close()
shutil.copytree(tmpdir.name, f'/tmp/{module_name}', dirs_exist_ok=True)
print(f'Keeping /tmp/{module_name}')
# Parse the config.xml file
root = ET.parse(f'{tmpdir.name}/config.xml').getroot()
params_full = dict()
if not args.is_config:
# Search for any element with our target text, make sure we found only one
xpath = f'.//*[.="{args.item_min}"]'
if args.root_elt != 'root':
root = root.find(f'.//{args.root_elt}')
key_elts = root.findall(xpath)
if len(key_elts) > 1:
sys.exit(f'Found {len(key_elts)} items with path "{xpath}"')
elif len(key_elts) == 0:
sys.exit(f'Cannot find minimally configured item with path "{xpath}"')
else:
key_elt = key_elts[0]
# This element should be the key for the items
module_key = key_elt.tag
if args.name_param:
name_param = args.name_param
else:
name_param = module_key
# The full node configuration element will be the parent
node_elt = key_elt.find('..')
module_node = node_elt.tag
# The "root" for this type of element is above that
root_elt = node_elt.find('..')
module_root = root_elt.tag
# Debug
if args.verbose >= 2:
print('item_min:\t' + ET.tostring(node_elt).decode())
# Let's use our node and key as a check
full_elt = root.find(f'.//{module_node}[{module_key}="{args.item_full}"]')
if full_elt is None:
sys.exit(f'Cannot find fully configured item with path ".//{module_node}[{module_key}="{args.item_full}"]"')
# Debug
if args.verbose >= 2:
print('item_full:\t' + ET.tostring(full_elt).decode())
# Collect the items for comparison with web elements and example values
for elt in full_elt:
if elt.tag == '':
continue
param = dict()
addr_elt = elt.find('address')
if addr_elt is not None:
param['example'] = addr_elt.text
param['address'] = True
elif elt.text is not None:
if elt.tag in params_full:
# Copy example and possibly other values from previous copy
param = params_full[elt.tag]
# If we have already need one of these, then it is a list
param['type'] = 'list'
# TODO - can we determine the type?
param['elements'] = 'str'
param['example2'] = elt.text.strip()
else:
param['type'] = 'str'
param['example'] = elt.text.strip()
# else:
# Likely a bool?
params_full[elt.tag] = param
# Try to determine the "proper" package name
if package != 'core':
package_elt = root.xpath(f"//package[translate(name/text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = '{package}']")
if package_elt:
package = package_elt[0].find('name').text
else:
print(f"WARNING: Could not find proper package name for {package}!")
# Parse the php file
if phpfile is not None:
found_save = False
with open(f'{tmpdir.name}/{phpfile}', 'r') as f:
for line in f:
if re.match(r'require_once', line):
php_requires += line
continue
if re.search(r'if \(\$_POST\[\'save\']', line):
found_save = True
continue
if found_save:
if re.match(r'}', line):
found_save = False
else:
php_save += re.sub(r'\t', ' ', re.sub(r'^\t', '', line))
subsystem_search = re.search(r'subsystem_dirty\(\'(.*)\'\)', line)
if subsystem_search:
php_subsystem = subsystem_search.group(1)
# See if this is not a proper form URL
if len(html.forms) != 1 or len(html.forms[0].inputs) <= 1:
action_buttons_urls = html.find('.//nav[@class="action-buttons"]/a')
if action_buttons_urls is not None:
action_href = re.sub(r'\?.*', '', action_buttons_urls.attrib["href"])
sys.exit(f'ERROR: This does not appear to be a proper form URL, you probably want {uri.scheme}://{uri.netloc}/{action_href}')
else:
sys.exit(f'ERROR: This does not appear to be a proper form URL, do you need a ? parameter?')
# TODO - For packages we could parse /usr/local/pkg/{package}.xml instead
# Make sure a string has a trailing period
def enforce_period(s):
if len(s) > 0 and s[-1] != '.':
s += '.'
return s
# Collected parameters from the web form
params = dict()
# Collect the input elements
for input in html.forms[0].inputs:
# Skip internal items
if input.name == '__csrf_magic':
continue
param = dict(description='')
if args.verbose >= 2:
print(f'attrib={input.attrib}')
if isinstance(input, lxml.html.InputElement):
if input.tail is not None:
input.tail = input.tail.strip()
if args.verbose >= 2:
print(f'input name={input.name} id={input.get("id")} type={input.type} value={input.value} '
f'text={input.text} title={input.get("title")} tail={input.tail}')
if input.type == 'checkbox':
param['type'] = 'bool'
param['value'] = input.attrib['value'].strip()
param['example'] = 'true'
elif input.type == 'number':
param['type'] = 'int'
if input.value is not None:
param['default'] = input.value
elif input.type == 'password':
param['type'] = 'str'
param['password'] = True # TODO - set nolog
elif input.type == 'radio':
# Radio buttons are a series of individual elements
if input.name in params:
param = params[input.name]
param['choices'].append(input.attrib['value'])
if input.checked:
param['default'] = input.attrib['value']
else:
param['type'] = 'str'
param['choices'] = [ input.attrib['value'] ]
if input.checked:
param['default'] = input.attrib['value']
elif input.type == 'text':
param['type'] = 'str'
if input.value is not None:
param['default'] = input.value
# TODO - handle placeholder as 'default' value - description? create_default? example?
for attr in ['min', 'placeholder', 'step']:
if attr in input.attrib:
param[attr] = input.attrib[attr]
# Text sometimes is after the input element inside the enclosing <label>
if input.tail and input.type != 'radio':
param['description'] = enforce_period(input.tail)
elif isinstance(input, lxml.html.SelectElement):
if args.verbose >= 2:
print(f'Found select element: name={input.name} value={input.value} value_options={input.value_options} multiple={input.multiple} attrib={input.attrib}')
# Strip any trailing []
input.name = re.sub(r'\[]$', '', input.name)
if input.attrib.get('class') == 'form-control' and input.attrib.get('data-toggle') == 'collapse':
args.type_param = input.name
if input.value is not None:
param['default'] = input.value
if input.value_options is not None:
if input.name == 'interface':
param['type'] = 'str'
# If a GW Group is present, allow them - this would be better to check for GW Group in the option text
# but this would require extracting that which will take a bit of work
if any('GW' in s for s in input.value_options):
param['parse'] = 'p2o_interface_with_gwgroup'
if 'p2o_interface_with_gwgroup' not in args_imports:
args_imports.append('p2o_interface_with_gwgroup')
# By default, interfaces will be parsed allowing virtual interfaces. If not allowed we need a different parser.
elif len(set(input.value_options).intersection(['enc0', 'openvpn'])) == 0:
param['parse'] = 'p2o_interface_without_virtual'
if 'p2o_interface_without_virtual' not in args_imports:
args_imports.append('p2o_interface_without_virtual')
else:
if input.multiple:
param['type'] = 'list'
param['default'] = []
for selected in input.value:
print(f'selected = {selected}')
param['default'].append(selected)
else:
param['type'] = 'str'
param['choices'] = input.value_options
param['multiple'] = input.multiple
elif input.tag == 'textarea':
param['type'] = 'str'
# <div class="form-group">
# <label class="col-sm-2 control-label">
# <span class="element-required">Hostname or IP address</span>
# </label>
# <div class="col-sm-10">
# <input class="form-control" name="ldap_host" id="ldap_host" type="text">
# <span class="help-block">NOTE: When using SSL/TLS or STARTTLS, this hostname MUST match a Subject Alternative Name (SAN) or the Common Name (CN) of the LDAP server SSL/TLS Certificate.</span>
# </div>
# </div>
form_groups = input.xpath('./ancestor::div[@class="form-group"]')
if form_groups:
form_group = form_groups[0]
descr_elt = form_group.find('*span')
if descr_elt is not None:
if descr_elt.text:
if args.verbose >= 2:
print(f'Found descr_elt {descr_elt.tag} {descr_elt.text} {descr_elt.attrib}')
if input.get('type') == 'radio':
param['description'] = f'{descr_elt.text.strip()} of the {module_name}.'
else:
param['description'] += f'{descr_elt.text.strip()} of the {module_name}.'
if 'class' in descr_elt.attrib and descr_elt.attrib['class'] == 'element-required':
if args.verbose >= 2:
print(f'Found element-required')
param['required'] = True
else:
if args.verbose >= 3:
print(f'Could not find descriptive element for item')
help_elt = form_group.find('./div/span[@class="help-block"]')
if help_elt is not None and help_elt.text is not None:
if args.verbose >= 2:
print(f'help_elt text {help_elt.text.strip()}')
descr = enforce_period(help_elt.text.strip())
if input.get('type') == 'radio':
param['description'] = f' {descr}'
else:
param['description'] += f' {descr}'
if args.verbose >= 2:
print(f'Final param = {param}\n')
params[input.name] = param
if not args.is_config:
# Key is handled separately from other parameters so remove it
# TODO - keep the description, etc?
params.pop(module_key, None)
# Debug
if args.verbose >= 2:
print(f'Web paramters: {params.keys()}')
# Determine the type of the bool parameters
bool_style = None
bool_values = {}
for name, param in params.items():
if param.get('type') != 'bool':
continue
bool_values[name] = param['value']
if bool_style is None:
bool_style = param['value']
elif bool_style != param['value']:
# Not consistent
bool_style = 'inconsistent'
# Determine if the form produces different types of items
if args.type_param in params_full:
# The type of item is recorded in the item configuration
module_type = params_full[args.type_param]['example']
if args.type_suffix is True:
module_name += f'_{module_type}'
if isinstance(args.type_suffix, str):
module_name += f'_{args.type_suffix}'
elif (match := re.match(r'type=([^&]+)', uri.query)):
module_type = match.group(1)
module_name += f'_{module_type}'
elif args.type_param in params:
# The type of item is purely a fuction of the web form
choices = params[args.type_param].get('choices')
if choices is None:
sys.exit(f"Detected item type parameter '{args.type_param}' but no choices parameter in {params[args.type_param]}. You must set --type-suffix to something.")
if args.type_suffix not in params[args.type_param]['choices']:
sys.exit(f"Detected item type parameter '{args.type_param}' with choices {params[args.type_param]['choices']}. You must set --type-suffix to one of these.")
else:
module_type = args.type_suffix
module_name += f'_{args.type_suffix}'
params_full[args.type_param] = params[args.type_param]
args.keep_params = True
else:
module_type = None
if not args.is_config:
# Consistency
params_web_only = list(set(params.keys()) - set(params_full.keys()))
if args.verbose >= 2:
print('Web parameters not in xml: ' + str(params_web_only))
# Cleanup extra web parameters
for param in params_web_only:
# See if the items are numbered, likely maps to an unnumbered XML tag
newp = re.sub(r'0$', '', param)
if newp != param:
if newp in params_full:
if args.verbose >= 2:
print(f'Renaming {param} to {newp}')
params[newp] = params.pop(param)
continue
# See if the items are prefixed by a type, likely maps to un-prefixed XML tag
newp = re.sub(f'^{module_type}_', '', param)
if newp != param:
if newp in params_full and newp not in params:
if args.verbose >= 2:
print(f'Renaming {param} to {newp}')
params[newp] = params.pop(param)
continue
# Common renamings
for f, t in [('dst', 'destination'), ('src', 'source')]:
if param == f and t in params_full:
if args.verbose >= 2:
print(f'Renaming {f} to {t}')
params[t] = params.pop(f)
break
else:
# Otherwise, drop - probably just used to construct the final elements
if param in params and not args.keep_params:
if args.verbose >= 2:
print(f'Removing {param}')
del params[param]
params_xml_only = list(set(params_full.keys()) - set(params.keys()) - {module_key, 'refid'})
if args.verbose >= 2:
print(f'XML parameters not in web: {params_xml_only}\n')
if len(params_xml_only) > 0:
print(f'You may need to use {module_node.upper()}_MAP_PARAMS')
for param in params_xml_only:
params[param] = params_full[param]
# Create some sample descriptions
for name, param in params.items():
# TODO - wrap long descriptions
if 'description' not in param or param['description'] == '':
param['description'] = f'The {name} of the {module_node}.'
if 'example' not in param or param['example'] == '':
if name in params_full and 'example' in params_full[name]:
param['example'] = params_full[name]['example']
if 'default' in param:
param['description'] += f' Defaults to {param["default"]}.'
if args.is_config:
module_base = 'PFSenseModuleConfigBase'
# Generate PFSense module name
if package == 'core':
pfsense_module_name = 'PFSense' + ''.join([word.capitalize() for word in module_name.split('_')]) + 'Module'
else:
pfsense_module_name = f'PFSense{package}' + ''.join([word.capitalize() for word in module_name.split('_')[1:]]) + 'Module'
# Template variables
context = dict(
module_base=module_base,
module_name=module_name,
module_root=module_root,
module_node=module_node,
module_key=module_key,
pfsense_module_name=pfsense_module_name,
params=params,
params_xml_only=params_xml_only,
name_param=name_param,
bool_style=bool_style,
bool_values=bool_values,
args_imports=args_imports,
is_config=args.is_config,
is_simple_package=is_simple_package,
is_full_package=is_full_package,
package=package,
author_name=args.author_name,
author_email=args.author_email,
author_handle=args.author_handle,
php_requires=php_requires,
php_save=php_save,
php_subsystem=php_subsystem,
year=datetime.date.today().year,
)
# Render our module!
jenv = jinja2.Environment(loader=jinja2.FileSystemLoader("misc/"), trim_blocks=True, keep_trailing_newline=True)
jenv.filters['dict2items'] = dict_to_list_of_dict_key_value_elements
jenv.filters['unique'] = unique
template = jenv.get_template("pfsense_module.py.j2")
filename = f'plugins/modules/pfsense_{module_name}.py'
if os.path.isfile(filename) and not args.force:
sys.exit(f'{filename} already exists! Use --force to overwrite.')
if args.verbose > 0:
print(f'Writing module {filename} with {context}')
else:
print(f'Writing module {filename}')
f = open(f'{filename}', 'w')
f.write(template.render(context))
f.close()
================================================
FILE: misc/pytest
================================================
#!/bin/sh
misc/local2ansible
if [ ! -f .coveragerc ]; then
cp -f misc/.coveragerc .
fi
python3 -m pytest -v -r a test/units/modules/network/pfsense/ test/units/plugins/lookup/test_pfsense.py --cov --cov-report html $*
================================================
FILE: misc/run_ansible_sanity_tests
================================================
#!/bin/sh
if [ -z "${ANSIBLE_HOME}" ]
then
echo "ANSIBLE_HOME is undefined. Go into ansible directory and run 'source hacking/env-setup'"
exit 1
fi
misc/local2ansible
TO_CHECK='lib/ansible/modules/network/pfsense/
lib/ansible/module_utils/network/pfsense/
lib/ansible/plugins/lookup/pfsense.py
test/units/modules/network/pfsense/'
cd ${ANSIBLE_HOME}
ansible-test sanity --python 3.5 ${TO_CHECK} $*
ansible-test sanity --python 2.7 ${TO_CHECK} $*
================================================
FILE: misc/setup_units_tests
================================================
#!/bin/sh
if [ -z "${ANSIBLE_HOME}" ]
then
echo "ANSIBLE_HOME is undefined. Go into ansible directory and run 'source hacking/env-setup'"
exit 1
fi
rm -f test/units/compat test/units/modules/utils.py test/units/modules/utils.pyc test/units/module_utils test/units/__init__.py test/units/__init__.pyc test/units/modules/__init__.py test/units/modules/__init__.pyc
ln -s ${ANSIBLE_HOME}/test/units/compat test/units/compat
ln -s ${ANSIBLE_HOME}/test/units/modules/utils.py test/units/modules/utils.py
ln -s ${ANSIBLE_HOME}/test/units/module_utils test/units/module_utils
touch test/units/__init__.py
touch test/units/modules/__init__.py
================================================
FILE: plugins/lookup/pfsense.py
================================================
# -*- coding: utf-8 -*-
# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = """
name: pfsense
author: Frederic Bor (@f-bor)
version_added: 0.1.0
short_description: Generate pfSense aliases, rules and rule_separators
description:
- This lookup plugin is designed to be used with pfsense_aggregate module.
It takes a yaml file and generate list of aliases and rules definitions.
The aim is to be able to easily manage a fleet of pfSenses and avoiding any
redundant work, like defining the sames hosts/ports aliases or rules
on multiples pfSenses. The plugin determine what is required to be defined
on each pfsense, leaving to the network administrator only the task of updating
the yaml definition file.
options:
file:
description: The yaml file defining the network
type:
description: What to generate
choices:
- aliases
- rules
- rule_separators
"""
EXAMPLES = """
- name: Get all aliases to be defined
debug:
aliases: "{{ lookup('pfsensible.core.pfsense', 'all_pf_defs.yml', 'aliases') }}"
- name: Get all rules to be defined
debug:
rules: "{{ lookup('pfsensible.core.pfsense', 'all_pf_defs.yml', 'rules') }}"
- name: Get all rule_separators to be defined
debug:
rule_separators: "{{ lookup('pfsensible.core.pfsense', 'all_pf_defs.yml', 'rule_separators') }}"
"""
RETURN = """
_list:
description:
- list of dictionaries with aliases, rules or rule_separators
type: list
"""
"""
To determine if a rule and corresponding aliases has to be declared on a pfsense
and on which interfaces, the plugin check if rule source or destination is
matching any local or routed network on the pfsense. To avoid having every rule
declared on a wan interface, if a rule can be declared on multiple interfaces
it is not on the ones routing 0.0.0.0/0 if there is another which is not routing it.
If a network is declared as remote (routed thru) on an interface and is also defined
as the local network on an interface of the target pfsense, the local network is preffered.
The same apply to adjacent networks, which indicates neighbor networks that are routed thru a pfSense.
Following pfSense rule definition (one host/alias per source/destination,
one port/alias per source/destination), each rule declared in the yaml is breaked
into smaller rules until having rules than can be declared.
The generated rules order follows the yaml file rules order.
Rule separators name are taken from parent rules' groups (see 'ADMIN', 'VOIP',
'MISC' or 'ACTIVE DIRECTORY' in the example below). Nested groups generate separators
names in the form 'GROUP1 - GROUP2 - ...'
You can define a default value for all rules and subrules of a separator using
the name 'options'. The parameters supported this way are gateway, log, queue, ackqueue,
in_queue, out_queue and sched. You can override those default values setting other values
on a deeper options set or inside the rule definition.
You can use an extra parameter in rules and options, filter, to restrict the rule
generation only to the pfsenses set in this parameter. Same goes for ifilter and interfaces.
The yaml file must include the following definitions to describe the network topology:
- pfsenses
- rules
- hosts_aliases
- ports_aliases
You can run the plugin alone to debug rules and aliases generation, for example:
- ./lookup_plugins/pfsense.py defs.yml pf1
- ./lookup_plugins/pfsense.py defs.yml pf1 ping_from_poc3
A typical pfsense_aggregate task using the lookup plugin will look like this:
tasks:
- name: "setup aliases & rules"
pfsense_aggregate:
purge_aliases: true
purge_rules: true
purge_rule_separators: true
aggregated_aliases: |
{{ lookup('pfsensible.core.pfsense', 'defs.yml', 'aliases') }}
aggregated_rules: |
{{ lookup('pfsensible.core.pfsense', 'defs.yml', 'rules') }}
aggregated_rule_separators: |
{{ lookup('pfsensible.core.pfsense', 'defs.yml', 'rule_separators') }}
Here is an example of yaml file:
---
pfsenses:
pf1: {
interfaces: {
lan: { ip: 192.168.1.1/24, adjacent_networks: lan_data_poc4 },
lan_100: { ip: 172.16.1.1/24 },
vpn: { remote_networks: lan_data_all lan_voip_all},
}
}
pf2: {
interfaces: {
lan: { ip: 192.168.2.1/24 },
lan_100: { ip: 172.16.2.1/24 },
vpn: { remote_networks: lan_data_all lan_voip_all},
}
}
pf3: {
interfaces: {
bridge_lan: { ip: 192.168.3.1/24, remote_networks: lan_data_all, bridge: True },
bridge_lan_100: { ip: 172.16.3.1/24, remote_networks: lan_voip_all, bridge: True },
wan: { remote_networks: 0.0.0.0/0 }
}
}
rules:
options: { log: yes }
ADMIN:
antilock_out: { src: any, dst: any, protocol: tcp, dst_port: port_ssh port_http 443 }
admin_bypass: { src: srv_admin, dst: any }
MISC:
ping_from_poc3: { src: lan_poc3_all, dst: srv_admin, protocol: icmp }
VOIP:
voip_conf_tftp: { src: all_ipbx, dst: lan_voip_all, dst_port: 69, protocol: udp }
ACTIVE DIRECTORY:
ads_to_ads_tcp: { src: all_ads, dst: all_ads, dst_port: port_dns port_ldap port_ldap_ssl, protocol: tcp }
ads_to_ads_udp: { src: all_ads, dst: all_ads, dst_port: port_dns port_ldap, protocol: udp }
DNS:
options: { log: no }
any_to_local_dns: {src: any, dst: all_ads, dst_port: port_dns, protocol: udp }
hosts_aliases:
# hosts
ipbx_poc1: { ip: 172.16.1.3 }
ipbx_poc2: { ip: 172.16.2.3 }
ipbx_poc3: { ip: 172.16.3.3 }
all_ipbx: { ip: ipbx_poc1 ipbx_poc2 ipbx_poc3 }
ad_poc1: { ip: 192.168.1.3 }
ad_poc2: { ip: 192.168.2.3 }
ad_poc3: { ip: 192.168.3.3 }
all_ads: { ip: ad_poc1 ad_poc2 ad_poc3 }
# networks
lan_voip_poc1: { ip: 172.16.1.0/24 }
lan_voip_poc2: { ip: 172.16.2.0/24 }
lan_voip_poc3: { ip: 172.16.3.0/24 }
lan_voip_all : { ip: lan_voip_poc1 lan_voip_poc2 lan_voip_poc3 }
lan_data_poc1: { ip: 192.168.1.0/24 }
lan_data_poc2: { ip: 192.168.2.0/24 }
lan_data_poc3: { ip: 192.168.3.0/24 }
lan_data_poc4: { ip: 192.168.4.0/24 }
lan_data_all : { ip: lan_data_poc1 lan_data_poc2 lan_data_poc3 lan_data_poc4 }
lan_poc3_all : { ip: lan_voip_poc3 lan_data_poc3 }
srv_admin: { ip: 192.168.1.165 }
ports_aliases:
port_ssh: { port: 22 }
port_telnet: { port: 23 }
port_dns: { port: 51 }
port_http: { port: 80 }
port_ldap: { port: 389 }
port_ldap_ssl: { port: 636 }
"""
from copy import copy, deepcopy
from collections import OrderedDict
from ansible.utils.display import Display
from functools import lru_cache
try:
from dns import resolver, exception
except ImportError as imp_exc:
DNS_IMPORT_ERROR = imp_exc
else:
DNS_IMPORT_ERROR = None
import argparse
import json
import re
import socket
import sys
import yaml
import traceback
import os
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
import ipaddress
OPTION_FIELDS = [
'gateway', 'log', 'queue', 'ackqueue', 'in_queue', 'out_queue', 'queue_error', 'icmptype', 'filter', 'efilter', 'ifilter', 'eifilter', 'sched', 'quick',
'direction', 'staticnatport', 'ipprotocol',
'associated_rule', 'natreflection',
]
OUTPUT_OPTION_FIELDS = ['gateway', 'log', 'queue', 'ackqueue', 'in_queue', 'out_queue', 'queue_error', 'icmptype', 'sched', 'quick', 'direction', 'ipprotocol']
OUTPUT_SRC_NAT_OPTION_FIELDS = ['staticnatport', 'ipprotocol']
OUTPUT_DST_NAT_OPTION_FIELDS = ['associated_rule', 'natreflection']
display = Display()
def to_unicode(string):
""" return a unicode representation of string if required """
if sys.version_info[0] >= 3:
return string
return string.decode("utf-8")
def ordered_load(stream, loader_cls=yaml.SafeLoader, object_pairs_hook=OrderedDict):
""" load and return yaml data from stream using ordered dicts """
class OrderedLoader(loader_cls):
def __init__(self, stream):
self._root = os.path.split(stream.name)[0]
super(OrderedLoader, self).__init__(stream)
def include(self, node):
filename = os.path.join(self._root, self.construct_scalar(node))
with open(filename, 'r') as f:
return yaml.load(f, OrderedLoader)
def construct_mapping(loader, node):
loader.flatten_mapping(node)
return object_pairs_hook(loader.construct_pairs(node))
if DNS_IMPORT_ERROR:
raise AnsibleError('dns must be installed to use ordered_load from this plugin') from DNS_IMPORT_ERROR
OrderedLoader.add_constructor(
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
construct_mapping)
OrderedLoader.add_constructor(
'!include',
OrderedLoader.include)
return yaml.load(stream, OrderedLoader)
def static_vars(**kwargs):
""" static decorator to declare static vars """
def decorate(func):
""" static decorator func """
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate
@lru_cache(maxsize=None)
def to_ip_address(address):
""" convert address to IPv4Address or IPv6Address """
return ipaddress.ip_address(to_unicode(address))
@lru_cache(maxsize=None)
def to_ip_network(address, strict=True):
""" convert address to IPv4Network or IPv6Network """
return ipaddress.ip_network(to_unicode(address), strict=strict)
@lru_cache(maxsize=None)
@static_vars(
classA=ipaddress.IPv4Network((u"10.0.0.0", u"255.0.0.0")),
classB=ipaddress.IPv4Network((u"172.16.0.0", u"255.240.0.0")),
classC=ipaddress.IPv4Network((u"192.168.0.0", u"255.255.0.0")),
)
def is_private_ip(address):
""" check if ip address is class A, B or C """
if not isinstance(address, ipaddress.IPv4Address):
ip_address = to_ip_address(to_unicode(address))
else:
ip_address = address
return ip_address in is_private_ip.classA or ip_address in is_private_ip.classB or ip_address in is_private_ip.classC
@lru_cache(maxsize=None)
@static_vars(
classA=ipaddress.IPv4Network((u"10.0.0.0", u"255.0.0.0")),
classB=ipaddress.IPv4Network((u"172.16.0.0", u"255.240.0.0")),
classC=ipaddress.IPv4Network((u"192.168.0.0", u"255.255.0.0")),
)
def is_private_network(address):
""" check if network is class A, B or C """
if not isinstance(address, ipaddress.IPv4Network):
net = to_ip_network(to_unicode(address))
else:
net = address
return net.subnet_of(is_private_network.classA) or net.subnet_of(is_private_network.classB) or net.subnet_of(is_private_network.classC)
@lru_cache(maxsize=None)
@static_vars(
ip_broadcast=ipaddress.IPv4Address((u"255.255.255.255")),
net_multicast=ipaddress.IPv4Network((u"224.0.0.0", u"255.255.255.0")),
)
def is_ip_broadcast(address):
""" check if ip address is ip broadcast address """
if not isinstance(address, ipaddress.IPv4Address):
ip_address = to_ip_address(to_unicode(address))
else:
ip_address = address
return ip_address == is_ip_broadcast.ip_broadcast or ip_address in is_ip_broadcast.net_multicast
@static_vars(re_cache=None)
def is_fqdn(address):
""" check if address is a fqdn address """
if is_fqdn.re_cache is None:
is_fqdn.re_cache = re.compile(r'(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)')
return is_fqdn.re_cache.match(address) is not None
def resolve_hostname(address, dns_servers=None):
""" get ip for hostname """
if dns_servers is None:
try:
resolved_ip = socket.gethostbyname(address)
return resolved_ip
except socket.gaierror:
pass
msg = "Unable to resolve: {0}".format(address)
else:
if DNS_IMPORT_ERROR:
raise AnsibleError('dns must be installed to use ordered_load from this plugin') from DNS_IMPORT_ERROR
error = None
try:
res = resolver.Resolver()
res.timeout = 15
res.lifetime = 15
res.nameservers = dns_servers
answers = res.query(address)
if answers:
return answers[0].address
except exception.Timeout:
error = 'timeout'
msg = "Unable to resolve: {0} using {1} dns servers".format(address, ','.join(dns_servers))
if error is not None:
msg += ' ({0})'.format(error)
raise AssertionError(msg)
def is_valid_ip(address):
""" validate ip address format """
try:
to_ip_address(to_unicode(address))
return True
except ValueError:
return False
def is_valid_port(port):
""" validate port format """
if not port.isdigit():
return False
nport = int(port)
return nport >= 0 and nport <= 65535
def is_valid_port_range(port_range):
""" validate port range format """
group = re.match(r'^(\d+)-(\d+)$', port_range)
if not group:
return False
nport1 = int(group.group(1))
nport2 = int(group.group(2))
return nport1 >= 0 and nport1 <= 65535 and nport2 >= 0 and nport2 <= 65535
def is_valid_network(address):
""" validate network address format """
try:
to_ip_network(to_unicode(address))
return True
except ValueError:
return False
def rule_product_dict(tab, rule, field, out_field=None):
""" Return cartesian product between rule[field] and tab as dicts """
if field not in rule:
return tab
if not out_field:
out_field = field
out = []
for new_val in rule[field].split():
for existing_val in tab:
obj = existing_val.copy()
obj[out_field] = new_val
out.append(obj)
return out
def rule_product_ports(rule, field, field_port):
""" Return cartesian product between rule[field] and field_port as string """
if field_port not in rule:
return rule[field]
aliases = rule[field].split()
ports = rule[field_port].split()
ret = []
for alias in aliases:
added = False
for port in ports:
if port:
ret.append(alias + ":" + port)
added = True
if not added:
ret.append(alias)
return ' '.join(ret)
def get_bool(values, field):
""" Return boolean field value from values """
field_value = False
if isinstance(values[field], bool):
field_value = values[field]
elif isinstance(values[field], str):
if values[field].lower() in ['yes', 'true']:
field_value = True
elif values[field].lower() not in ['no', 'false']:
raise AnsibleError('{0} must be yes/no or true/false (got "{1}")'.format(field, values[field]))
return field_value
class PFSenseHostAlias(object):
""" Class holding structured pfsense host alias definition """
def __init__(self):
self.name = None
self.descr = None
self.definition = []
self.ips = []
self.networks = []
self.dns = None
self.fake = False
# define all interfaces on which the alias may be defined as a local source
# interfaces['gw_poc1_1'] = ['lan', 'obs']
self.local_interfaces = {}
# define all interfaces on which the alias may be defined as a routed source
self.routed_interfaces = {}
self._computed = False
def copy(self):
copy_object = PFSenseHostAlias()
copy_object.name = self.name
copy_object.descr = self.descr
copy_object.dns = self.dns
copy_object.fake = self.fake
copy_object._computed = self._computed
copy_object.definition = self.definition[:]
# ips
copy_object.ips = self.ips[:]
# networks
copy_object.networks = self.networks[:]
# local_interfaces
for k, v in self.local_interfaces.items():
copy_object.local_interfaces[k] = v.copy()
# routed_interfaces
for k, v in self.routed_interfaces.items():
copy_object.routed_interfaces[k] = v.copy()
return copy_object
def __str__(self):
return "name={0}, descr={1}, definition={2}, ips={3}, networks={4}, local_interfaces={5}, routed_interfaces={6}, fake={7}".format(
self.name, self.descr, self.definition, self.ips, self.networks, self.local_interfaces, self.routed_interfaces, self.fake)
def compute_any(self, data):
""" Do all computations for object 'any' """
# we add all interfaces of all pfsenses
for pfsense in data.pfsenses_obj.values():
for interface in pfsense.interfaces.values():
self.local_interfaces[pfsense.name].append(interface.name)
self.routed_interfaces[pfsense.name].append(interface.name)
def compute_all(self, data):
""" Do all computations """
if not self._computed:
self._computed = True
if self.name != 'any':
self.compute_addresses(data)
self.compute_local_interfaces(data)
self.compute_routed_interfaces(data)
def compute_addresses(self, data):
""" Convert all aliases to structured ip addresses or networks """
todo = []
todo.extend(self.definition)
while todo:
address = todo.pop()
# special case when (self) is used in nat rules
if address == '':
continue
# it's an ip address
try:
host_ip = to_ip_address(to_unicode(address))
self.ips.append(host_ip)
continue
except ValueError:
pass
# it's an ip network
try:
net = to_ip_network(to_unicode(address))
self.networks.append(net)
continue
except ValueError:
pass
# it's a fqdn
if address not in data.all_aliases:
if is_fqdn(address):
resolved_ip = resolve_hostname(address, self.dns)
host_ip = to_ip_address(to_unicode(resolved_ip))
self.ips.append(host_ip)
continue
raise AssertionError("Invalid address: " + address + " for " + self.name)
# it's another alias
alias = data.hosts_aliases_obj.get(address)
if alias is not None:
if not alias._computed:
alias.compute_all(data)
self.ips += alias.ips
self.networks += alias.networks
continue
todo.extend(data.all_aliases[address]['ip'].split())
def _is_in_networks(self, interface, fcheckname):
""" check if an alias is in a network of an interface """
fcheck = getattr(interface, fcheckname)
for alias_ip in self.ips:
if is_ip_broadcast(alias_ip):
continue
if not fcheck(alias_ip):
return False
for alias_net in self.networks:
if not fcheck(alias_net):
return False
return True
def is_in_local_network(self, interface):
""" check if an alias is in the local network of an interface """
return self._is_in_networks(interface, 'local_network_contains')
def is_in_remote_networks(self, interface):
""" check if an alias is in the remote networks of an interface """
return self._is_in_networks(interface, 'remote_networks_contains')
def is_in_adjacent_networks(self, interface):
""" check if an alias is in the adjacent networks of an interface """
return self._is_in_networks(interface, 'adjacent_networks_contains')
def compute_routed_interfaces(self, data):
""" Find all interfaces on all pfsense where the alias may be used as a routed source """
for pfsense in data.pfsenses_obj.values():
# if the target alias is local, we do not consider the other interfaces
self.routed_interfaces[pfsense.name] = set()
if pfsense.name in self.local_interfaces:
continue
cache = pfsense._interfaces_remote_networks_contains_cache
_compute = pfsense._interfaces_network_contains
local_ifaces = self.routed_interfaces[pfsense.name]
for address in self.ips:
cache_key = id(address)
interfaces = cache.get(cache_key)
if interfaces is None:
interfaces = _compute(address, 'remote_networks')
cache[cache_key] = interfaces
local_ifaces.update(interfaces)
for address in self.networks:
cache_key = id(address)
interfaces = cache.get(cache_key)
if interfaces is None:
interfaces = _compute(address, 'remote_networks')
cache[cache_key] = interfaces
local_ifaces.update(interfaces)
def compute_local_interfaces(self, data):
""" Find all interfaces on all pfsense where the alias may be used as a local source """
for pfsense in data.pfsenses_obj.values():
self.local_interfaces[pfsense.name] = set()
cache = pfsense._interfaces_local_networks_contains_cache
_compute = pfsense._interfaces_network_contains
local_ifaces = self.local_interfaces[pfsense.name]
for address in self.ips:
cache_key = id(address)
interfaces = cache.get(cache_key)
if interfaces is None:
interfaces = _compute(address, 'local_networks')
cache[cache_key] = interfaces
local_ifaces.update(interfaces)
for address in self.networks:
cache_key = id(address)
interfaces = cache.get(cache_key)
if interfaces is None:
interfaces = _compute(address, 'local_networks')
cache[cache_key] = interfaces
local_ifaces.update(interfaces)
def is_whole_local(self, pfsense):
""" check if all ips/networks match a local network interface in pfense """
for alias_ip in self.ips:
if is_ip_broadcast(alias_ip):
continue
if not pfsense.any_local_network_contains(alias_ip):
return False
for alias_net in self.networks:
if not pfsense.any_local_network_contains(alias_net):
return False
return True
def routed_by_interfaces(self, pfsense, use_remote_networks=True):
""" return all interfaces for which all ips/networks match an adjacent/remote network in pfsense """
all_interfaces = set()
# we always search through all interfaces to handle cases with internet
for alias_ip in self.ips:
interfaces = pfsense.interfaces_adjacent_or_remote_networks_contains(alias_ip, use_remote_networks=True)
interfaces = pfsense.hack_internet_routing(interfaces, alias_ip, use_remote_networks=True)
all_interfaces.update(interfaces)
for alias_net in self.networks:
interfaces = pfsense.interfaces_adjacent_or_remote_networks_contains(alias_net, use_remote_networks=True)
interfaces = pfsense.hack_internet_routing(interfaces, alias_net, use_remote_networks=True)
all_interfaces.update(interfaces)
# if we didn't want the remote interfaces, we only keep the adjacents
if not use_remote_networks:
interfaces = set()
for interface in all_interfaces:
if self.is_in_adjacent_networks(pfsense.interfaces[interface]):
interfaces.add(interface)
all_interfaces = interfaces
return all_interfaces
def is_adjacent_or_remote(self, pfsense):
""" check if all ips/networks are in an adjacent/remote network in pfsense """
return len(self.routed_by_interfaces(pfsense, use_remote_networks=True)) > 0
def is_adjacent(self, pfsense):
""" check if all ips/networks are in an adjacent network in pfsense """
return len(self.routed_by_interfaces(pfsense, use_remote_networks=False)) > 0
def is_ip_broadcast(self):
""" check if an alias is the ip_broadcast """
if len(self.ips) != 1 or self.networks:
return False
return is_ip_broadcast(self.ips[0])
def is_whole_in_pfsense(self, pfsense):
""" check if all ips/networks have at least one interface in pfsense """
if self.name in pfsense.is_whole_in_pfsense_cache:
return pfsense.is_whole_in_pfsense_cache[self.name]
for alias_ip in self.ips:
if is_ip_broadcast(alias_ip):
pfsense.is_whole_in_pfsense_cache[self.name] = False
return False
if not pfsense.any_network_contains(alias_ip):
pfsense.is_whole_in_pfsense_cache[self.name] = False
return False
for alias_net in self.networks:
if not pfsense.any_network_contains(alias_net):
pfsense.is_whole_in_pfsense_cache[self.name] = False
return False
pfsense.is_whole_in_pfsense_cache[self.name] = True
return True
def is_whole_not_in_pfsense(self, pfsense):
""" check if all ips/networks have at least one interface in pfsense """
if self.name in pfsense.is_whole_not_in_pfsense_cache:
return pfsense.is_whole_not_in_pfsense_cache[self.name]
for alias_ip in self.ips:
if is_ip_broadcast(alias_ip):
pfsense.is_whole_not_in_pfsense_cache[self.name] = False
return False
if pfsense.any_network_contains(alias_ip):
pfsense.is_whole_not_in_pfsense_cache[self.name] = False
return False
for alias_net in self.networks:
if pfsense.any_network_contains(alias_net):
pfsense.is_whole_not_in_pfsense_cache[self.name] = False
return False
pfsense.is_whole_not_in_pfsense_cache[self.name] = True
return True
def is_whole_in_same_routing_ifaces(self, pfsense):
""" check if all ips/networks have the same interfaces in pfense """
if self.name in pfsense.is_whole_in_same_routing_ifaces_cache:
return pfsense.is_whole_in_same_routing_ifaces_cache[self.name]
# we loop through all ips/networks in the alias
# if there is any difference in the interfaces where the address need to be defined
# then we return False so the parent function split the alias
target_ar_interfaces = None
target_local_interfaces = None
for alias_ip in self.ips:
interfaces = pfsense.interfaces_adjacent_or_remote_networks_contains(alias_ip)
interfaces = pfsense.hack_internet_routing(interfaces, alias_ip)
if target_ar_interfaces is None:
target_ar_interfaces = interfaces
elif target_ar_interfaces ^ interfaces:
pfsense.is_whole_in_same_routing_ifaces_cache[self.name] = False
return False
interfaces = pfsense.interfaces_local_networks_contains(alias_ip)
interfaces = pfsense.hack_internet_routing(interfaces, alias_ip)
if target_local_interfaces is None:
target_local_interfaces = interfaces
elif target_local_interfaces ^ interfaces:
pfsense.is_whole_in_same_routing_ifaces_cache[self.name] = False
return False
for alias_net in self.networks:
interfaces = pfsense.interfaces_adjacent_or_remote_networks_contains(alias_net)
interfaces = pfsense.hack_internet_routing(interfaces, alias_net)
if target_ar_interfaces is None:
target_ar_interfaces = interfaces
elif target_ar_interfaces ^ interfaces:
pfsense.is_whole_in_same_routing_ifaces_cache[self.name] = False
return False
interfaces = pfsense.interfaces_local_networks_contains(alias_net)
interfaces = pfsense.hack_internet_routing(interfaces, alias_net)
if target_local_interfaces is None:
target_local_interfaces = interfaces
elif target_local_interfaces ^ interfaces:
pfsense.is_whole_in_same_routing_ifaces_cache[self.name] = False
return False
pfsense.is_whole_in_same_routing_ifaces_cache[self.name] = True
return True
def match_local_interface_ip(self, pfsense):
""" Return True if the alias IP matches one interface on the pfsense """
all_local_ips = pfsense._all_local_ips
for alias_ip in self.ips:
if alias_ip in all_local_ips:
return True
return False
class PFSenseRule(object):
""" Class holding structured pfsense rule declaration """
def __init__(self):
self.name = None
self.separator = None
self.src = []
self.src_port = []
self.dst = []
self.dst_port = []
self.src_nat = []
self.dst_nat = []
self.dst_nat_port = []
self.protocol = []
self.action = "pass"
self.options = dict()
self.floating = False
self.force = False
self.asymmetric = False
self.invert_dst = False
self.invert_src = False
self.invert_dst_nat = False
self.invert_src_nat = False
self.sub_rules = []
self.interfaces = None
self.generated_names = {}
def copy(self):
copy_object = PFSenseRule()
copy_object.name = self.name
copy_object.separator = self.separator
copy_object.src = [alias.copy() for alias in self.src]
copy_object.dst = [alias.copy() for alias in self.dst]
copy_object.src_port = self.src_port[:]
copy_object.dst_port = self.dst_port[:]
copy_object.src_nat = self.src_nat
copy_object.dst_nat = self.dst_nat
copy_object.dst_nat_port = self.dst_nat_port
copy_object.protocol = self.protocol
copy_object.action = self.action
copy_object.options = self.options
copy_object.floating = self.floating
copy_object.force = self.force
copy_object.asymmetric = self.asymmetric
copy_object.invert_dst = self.invert_dst
copy_object.invert_src = self.invert_src
copy_object.invert_dst_nat = self.invert_dst_nat
copy_object.invert_src_nat = self.invert_src_nat
copy_object.sub_rules = [rule.copy() for rule in self.sub_rules]
if self.interfaces is not None:
copy_object.interfaces = self.interfaces.copy()
else:
copy_object.interfaces = None
copy_object.generated_names = self.generated_names.copy()
return copy_object
def _copy_for_decompose(self):
""" Lightweight copy for rule decomposition - shares alias objects instead of deep-copying them.
Callers always replace src or dst immediately after copying. """
copy_object = PFSenseRule()
copy_object.name = self.name
copy_object.separator = self.separator
copy_object.src = list(self.src)
copy_object.dst = list(self.dst)
copy_object.src_port = self.src_port[:]
copy_object.dst_port = self.dst_port[:]
copy_object.src_nat = self.src_nat
gitextract_2409rtmf/
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows/
│ └── main.yml
├── .gitignore
├── CHANGELOG.rst
├── GENERATING_MODULES.md
├── LICENSE
├── README.md
├── changelogs/
│ ├── .plugin-cache.yaml
│ ├── 134_openvpn_digest.yml
│ ├── changelog.yaml
│ ├── config.yaml
│ └── fragments/
│ ├── 129_sshguard_whitelist.yaml
│ ├── 217_pfsense_setup_webguicert.yml
│ ├── 219_parse_address_ipv6.yml
│ ├── 223_fix_openvpn_alias_expansion.yml
│ ├── 224_add_dco_for_plus_versions.yml
│ ├── 226_dns_resolver.yaml
│ ├── 228_interface_diff.yml
│ ├── 238_pfsense_openvpn_server.yml
│ ├── 239_sync_config.yml
│ ├── 242_gateway_loss.yml
│ ├── 243_openvpn_client.yml
│ ├── 245_arg_route.yaml
│ ├── 248_class_level_imports.yaml
│ ├── 251_setup_hardware.yaml
│ ├── rule_pass_before_deny_ordering.yml
│ └── rule_protocol_any_with_ports.yml
├── examples/
│ ├── ipsec/
│ │ ├── README.md
│ │ ├── filter_plugins/
│ │ │ └── pfsense.py
│ │ ├── hosts
│ │ ├── ipsecs.yaml
│ │ ├── more.ipsecs.yaml
│ │ └── setup_ipsec.yml
│ ├── lookup/
│ │ ├── README.md
│ │ ├── hosts
│ │ ├── pfsense_definitions.yaml
│ │ └── setup_all_rules.yml
│ ├── pfsense.yml
│ ├── pfsense_setup.yml
│ └── roles/
│ ├── pfsense/
│ │ └── tasks/
│ │ ├── fail2ban.yml
│ │ └── main.yml
│ └── pfsense_setup/
│ ├── tasks/
│ │ ├── main.yml
│ │ └── setup_user.yml
│ └── templates/
│ └── nslcd.conf.j2
├── galaxy.yml
├── meta/
│ └── runtime.yml
├── misc/
│ ├── .coveragerc
│ ├── ansible2local
│ ├── local2ansible
│ ├── mkpfcollection
│ ├── mkpfsensible
│ ├── pfsense_module.py.j2
│ ├── pfsensible-generate-module
│ ├── pytest
│ ├── run_ansible_sanity_tests
│ └── setup_units_tests
├── plugins/
│ ├── lookup/
│ │ └── pfsense.py
│ ├── module_utils/
│ │ ├── __init__.py
│ │ ├── alias.py
│ │ ├── arg_route.py
│ │ ├── arg_validate.py
│ │ ├── default_gateway.py
│ │ ├── dhcp_server.py
│ │ ├── gateway.py
│ │ ├── haproxy_backend.py
│ │ ├── haproxy_backend_server.py
│ │ ├── interface.py
│ │ ├── interface_group.py
│ │ ├── ipsec.py
│ │ ├── ipsec_p2.py
│ │ ├── ipsec_proposal.py
│ │ ├── module_base.py
│ │ ├── module_config_base.py
│ │ ├── nat_outbound.py
│ │ ├── nat_port_forward.py
│ │ ├── openvpn_client.py
│ │ ├── openvpn_override.py
│ │ ├── openvpn_server.py
│ │ ├── pfsense.py
│ │ ├── route.py
│ │ ├── rule.py
│ │ ├── rule_separator.py
│ │ └── vlan.py
│ └── modules/
│ ├── pfsense_aggregate.py
│ ├── pfsense_alias.py
│ ├── pfsense_authserver_ldap.py
│ ├── pfsense_authserver_radius.py
│ ├── pfsense_ca.py
│ ├── pfsense_cert.py
│ ├── pfsense_default_gateway.py
│ ├── pfsense_dhcp_server.py
│ ├── pfsense_dhcp_static.py
│ ├── pfsense_dns_resolver.py
│ ├── pfsense_gateway.py
│ ├── pfsense_gateway_group.py
│ ├── pfsense_group.py
│ ├── pfsense_haproxy_backend.py
│ ├── pfsense_haproxy_backend_server.py
│ ├── pfsense_interface.py
│ ├── pfsense_interface_group.py
│ ├── pfsense_ipsec.py
│ ├── pfsense_ipsec_aggregate.py
│ ├── pfsense_ipsec_p2.py
│ ├── pfsense_ipsec_proposal.py
│ ├── pfsense_log_settings.py
│ ├── pfsense_nat_outbound.py
│ ├── pfsense_nat_port_forward.py
│ ├── pfsense_openvpn_client.py
│ ├── pfsense_openvpn_override.py
│ ├── pfsense_openvpn_server.py
│ ├── pfsense_phpshell.py
│ ├── pfsense_rewrite_config.py
│ ├── pfsense_route.py
│ ├── pfsense_rule.py
│ ├── pfsense_rule_separator.py
│ ├── pfsense_setup.py
│ ├── pfsense_shellcmd.py
│ ├── pfsense_user.py
│ └── pfsense_vlan.py
├── setup.cfg
└── tests/
├── plays/
│ ├── README.md
│ ├── ansible.cfg
│ ├── host_vars/
│ │ └── pfsense-test.yml
│ ├── hosts
│ ├── openvpn.yml
│ ├── tasks/
│ │ ├── test_interface_create.yml
│ │ ├── test_interface_group_create.yml
│ │ ├── test_interface_group_ifconfig_groups.yml
│ │ ├── test_openvpn_override_create.yml
│ │ ├── test_openvpn_override_delete.yml
│ │ ├── test_openvpn_override_file_exists.yml
│ │ ├── test_openvpn_server_create.yml
│ │ └── test_openvpn_server_delete.yml
│ └── templates/
│ ├── openvpn-override.j2
│ └── openvpn-server-config.ovpn.j2
├── sanity/
│ ├── ignore-2.14.txt
│ ├── ignore-2.15.txt
│ ├── ignore-2.16.txt
│ └── ignore-2.17.txt
└── unit/
└── plugins/
├── lookup/
│ └── test_pfsense.py
├── module_utils/
│ ├── fixtures/
│ │ └── pfsense_setup_config.xml
│ └── test_pfsense.py
└── modules/
├── __init__.py
├── fixtures/
│ ├── 2.4/
│ │ ├── pfsense_ipsec_aggregate_config.xml
│ │ ├── pfsense_ipsec_config.xml
│ │ └── pfsense_ipsec_proposal_config.xml
│ ├── pfsense_aggregate_config.xml
│ ├── pfsense_alias_config.xml
│ ├── pfsense_alias_null_config.xml
│ ├── pfsense_authserver_config.xml
│ ├── pfsense_ca_config.xml
│ ├── pfsense_cert_config.xml
│ ├── pfsense_dhcp_server_config.xml
│ ├── pfsense_dhcp_static_config.xml
│ ├── pfsense_dns_resolver_config_full.xml
│ ├── pfsense_dns_resolver_config_init.xml
│ ├── pfsense_gateway_config.xml
│ ├── pfsense_haproxy_backend_config.xml
│ ├── pfsense_haproxy_backend_server_config.xml
│ ├── pfsense_interface_config.xml
│ ├── pfsense_ipsec_aggregate_config.xml
│ ├── pfsense_ipsec_config.xml
│ ├── pfsense_ipsec_p2_config.xml
│ ├── pfsense_ipsec_proposal_config.xml
│ ├── pfsense_nat_outbound.xml
│ ├── pfsense_nat_port_forward_config.xml
│ ├── pfsense_openvpn_config.xml
│ ├── pfsense_route_config.xml
│ ├── pfsense_rule_config.xml
│ ├── pfsense_rule_separator_config.xml
│ ├── pfsense_setup_config.xml
│ ├── pfsense_syslog_config.xml
│ ├── pfsense_user_config.xml
│ └── pfsense_vlan_config.xml
├── pfsense_module.py
├── test_pfsense_aggregate.py
├── test_pfsense_alias.py
├── test_pfsense_alias_null.py
├── test_pfsense_authserver_ldap.py
├── test_pfsense_authserver_radius.py
├── test_pfsense_ca.py
├── test_pfsense_cert.py
├── test_pfsense_dhcp_server.py
├── test_pfsense_dhcp_static.py
├── test_pfsense_dns_resolver.py
├── test_pfsense_gateway.py
├── test_pfsense_haproxy_backend.py
├── test_pfsense_haproxy_backend_server.py
├── test_pfsense_interface.py
├── test_pfsense_interface_group.py
├── test_pfsense_ipsec.py
├── test_pfsense_ipsec_aggregate.py
├── test_pfsense_ipsec_p2.py
├── test_pfsense_ipsec_proposal.py
├── test_pfsense_log_settings.py
├── test_pfsense_nat_outbound.py
├── test_pfsense_nat_port_forward.py
├── test_pfsense_openvpn_override.py
├── test_pfsense_openvpn_server.py
├── test_pfsense_route.py
├── test_pfsense_rule.py
├── test_pfsense_rule_create.py
├── test_pfsense_rule_misc.py
├── test_pfsense_rule_noop.py
├── test_pfsense_rule_separator.py
├── test_pfsense_rule_update.py
├── test_pfsense_setup.py
├── test_pfsense_user.py
└── test_pfsense_vlan.py
SYMBOL INDEX (1760 symbols across 100 files)
FILE: examples/ipsec/filter_plugins/pfsense.py
function format_ipsec_aggregate_ipsecs (line 12) | def format_ipsec_aggregate_ipsecs(all_tunnels, pfname):
function format_ipsec_aggregate_proposals (line 48) | def format_ipsec_aggregate_proposals(all_tunnels, pfname):
function format_ipsec_aggregate_p2s (line 95) | def format_ipsec_aggregate_p2s(all_tunnels, pfname):
function format_ipsec_aggregate (line 165) | def format_ipsec_aggregate(*terms):
class FilterModule (line 181) | class FilterModule(object):
method filters (line 185) | def filters():
FILE: plugins/lookup/pfsense.py
function to_unicode (line 232) | def to_unicode(string):
function ordered_load (line 239) | def ordered_load(stream, loader_cls=yaml.SafeLoader, object_pairs_hook=O...
function static_vars (line 268) | def static_vars(**kwargs):
function to_ip_address (line 280) | def to_ip_address(address):
function to_ip_network (line 286) | def to_ip_network(address, strict=True):
function is_private_ip (line 297) | def is_private_ip(address):
function is_private_network (line 312) | def is_private_network(address):
function is_ip_broadcast (line 326) | def is_ip_broadcast(address):
function is_fqdn (line 336) | def is_fqdn(address):
function resolve_hostname (line 343) | def resolve_hostname(address, dns_servers=None):
function is_valid_ip (line 375) | def is_valid_ip(address):
function is_valid_port (line 384) | def is_valid_port(port):
function is_valid_port_range (line 393) | def is_valid_port_range(port_range):
function is_valid_network (line 404) | def is_valid_network(address):
function rule_product_dict (line 413) | def rule_product_dict(tab, rule, field, out_field=None):
function rule_product_ports (line 429) | def rule_product_ports(rule, field, field_port):
function get_bool (line 449) | def get_bool(values, field):
class PFSenseHostAlias (line 462) | class PFSenseHostAlias(object):
method __init__ (line 464) | def __init__(self):
method copy (line 482) | def copy(self):
method __str__ (line 508) | def __str__(self):
method compute_any (line 512) | def compute_any(self, data):
method compute_all (line 520) | def compute_all(self, data):
method compute_addresses (line 529) | def compute_addresses(self, data):
method _is_in_networks (line 579) | def _is_in_networks(self, interface, fcheckname):
method is_in_local_network (line 594) | def is_in_local_network(self, interface):
method is_in_remote_networks (line 598) | def is_in_remote_networks(self, interface):
method is_in_adjacent_networks (line 602) | def is_in_adjacent_networks(self, interface):
method compute_routed_interfaces (line 606) | def compute_routed_interfaces(self, data):
method compute_local_interfaces (line 634) | def compute_local_interfaces(self, data):
method is_whole_local (line 657) | def is_whole_local(self, pfsense):
method routed_by_interfaces (line 672) | def routed_by_interfaces(self, pfsense, use_remote_networks=True):
method is_adjacent_or_remote (line 698) | def is_adjacent_or_remote(self, pfsense):
method is_adjacent (line 702) | def is_adjacent(self, pfsense):
method is_ip_broadcast (line 706) | def is_ip_broadcast(self):
method is_whole_in_pfsense (line 712) | def is_whole_in_pfsense(self, pfsense):
method is_whole_not_in_pfsense (line 734) | def is_whole_not_in_pfsense(self, pfsense):
method is_whole_in_same_routing_ifaces (line 755) | def is_whole_in_same_routing_ifaces(self, pfsense):
method match_local_interface_ip (line 803) | def match_local_interface_ip(self, pfsense):
class PFSenseRule (line 812) | class PFSenseRule(object):
method __init__ (line 814) | def __init__(self):
method copy (line 839) | def copy(self):
method _copy_for_decompose (line 874) | def _copy_for_decompose(self):
method get_option (line 909) | def get_option(self, name):
method to_json (line 920) | def to_json(self):
class PFSenseRuleSeparator (line 953) | class PFSenseRuleSeparator(object):
method __init__ (line 955) | def __init__(self):
method __hash__ (line 961) | def __hash__(self):
method __eq__ (line 964) | def __eq__(self, other):
class PFSenseInterface (line 968) | class PFSenseInterface(object):
method __init__ (line 970) | def __init__(self):
method precompute_network_splits (line 990) | def precompute_network_splits(self):
method _networks_contains (line 1005) | def _networks_contains(address, networks):
method remote_networks_contains (line 1025) | def remote_networks_contains(self, address):
method adjacent_networks_contains (line 1034) | def adjacent_networks_contains(self, address):
method local_network_contains (line 1043) | def local_network_contains(self, address):
method are_in_same_network (line 1063) | def are_in_same_network(self, src, dst):
class PFSense (line 1080) | class PFSense(object):
method __init__ (line 1082) | def __init__(self, name, interfaces):
method any_adjacent_networks_contains (line 1098) | def any_adjacent_networks_contains(self, address):
method any_remote_networks_contains (line 1102) | def any_remote_networks_contains(self, address):
method any_local_network_contains (line 1106) | def any_local_network_contains(self, address):
method any_network_contains (line 1110) | def any_network_contains(self, address):
method _get_iface_networks (line 1114) | def _get_iface_networks(self, attr):
method _interfaces_network_contains (line 1122) | def _interfaces_network_contains(self, address, networks_name):
method interfaces_local_networks_contains (line 1149) | def interfaces_local_networks_contains(self, address):
method interfaces_remote_networks_contains (line 1158) | def interfaces_remote_networks_contains(self, address):
method interfaces_adjacent_networks_contains (line 1167) | def interfaces_adjacent_networks_contains(self, address):
method interfaces_adjacent_or_remote_networks_contains (line 1176) | def interfaces_adjacent_or_remote_networks_contains(self, address, use...
method hack_internet_routing (line 1183) | def hack_internet_routing(self, interfaces, address, use_remote_networ...
class PFSenseData (line 1226) | class PFSenseData(object):
method __init__ (line 1229) | def __init__(self, hosts_aliases, ports_aliases, pfsenses, rules, targ...
method all_aliases (line 1253) | def all_aliases(self):
method hosts_aliases (line 1258) | def hosts_aliases(self):
method ignored_aliases (line 1263) | def ignored_aliases(self):
method hosts_aliases_obj (line 1268) | def hosts_aliases_obj(self):
method ports_aliases (line 1273) | def ports_aliases(self):
method pfsenses (line 1278) | def pfsenses(self):
method pfsenses_obj (line 1283) | def pfsenses_obj(self):
method rules_obj (line 1288) | def rules_obj(self):
method rules (line 1293) | def rules(self):
method ignored_rules (line 1298) | def ignored_rules(self):
method rules_separators (line 1303) | def rules_separators(self):
method target_name (line 1308) | def target_name(self):
method target (line 1313) | def target(self):
method target (line 1318) | def target(self, target):
method errors (line 1323) | def errors(self):
method set_error (line 1327) | def set_error(self, error):
method is_child_def (line 1333) | def is_child_def(values):
method unalias_ip (line 1340) | def unalias_ip(self, alias):
method get_hosts_alias (line 1355) | def get_hosts_alias(self, hosts, ips, networks, _basename):
method get_ports_alias (line 1399) | def get_ports_alias(self, ports, _basename):
class PFSenseDataParser (line 1428) | class PFSenseDataParser(object):
method __init__ (line 1431) | def __init__(self, data):
method check_alias_name (line 1435) | def check_alias_name(name):
method parse_host_alias (line 1441) | def parse_host_alias(self, obj, src_name, type_name, name, allow_any, ...
method parse_hosts_aliases (line 1496) | def parse_hosts_aliases(self):
method check_port_alias (line 1547) | def check_port_alias(self, ports, src_name, type_name, name):
method parse_ports_aliases (line 1572) | def parse_ports_aliases(self):
method create_obj_any_alias (line 1611) | def create_obj_any_alias(self):
method create_obj_host_alias (line 1625) | def create_obj_host_alias(self, src, dns_servers=None):
method create_obj_rule_from_def (line 1637) | def create_obj_rule_from_def(self, name, rule, separator):
method parse_rules (line 1744) | def parse_rules(self, parent=None, parent_separator=None):
method parse_target_name (line 1845) | def parse_target_name(self):
method check_tcp_udp (line 1853) | def check_tcp_udp(self, rule, name):
method check_pfsense_interfaces_objs (line 1864) | def check_pfsense_interfaces_objs(self, interfaces, name):
method create_pfsenses_aliases (line 1877) | def create_pfsenses_aliases(self):
method parse_pfsense_interfaces (line 2111) | def parse_pfsense_interfaces(self, pfsense, name):
method parse_pfsenses (line 2209) | def parse_pfsenses(self):
method parse_hosts_aliases_objs (line 2252) | def parse_hosts_aliases_objs(self):
method parse (line 2259) | def parse(self):
class PFSenseRuleDecomposer (line 2273) | class PFSenseRuleDecomposer(object):
method __init__ (line 2276) | def __init__(self, data):
method host_separate (line 2279) | def host_separate(self, host):
method host_separate_by_iface (line 2309) | def host_separate_by_iface(self, host):
method separate_aliases (line 2329) | def separate_aliases(self, rule, field, attr, func):
method decompose_rule (line 2342) | def decompose_rule(self, rule):
method decompose_rules (line 2380) | def decompose_rules(self):
class PFSenseAliasFactory (line 2394) | class PFSenseAliasFactory(object):
method __init__ (line 2397) | def __init__(self, data):
method add_host_alias_rec (line 2400) | def add_host_alias_rec(self, alias, aliases):
method add_port_alias_rec (line 2413) | def add_port_alias_rec(self, alias, aliases):
method add_hosts_aliases (line 2423) | def add_hosts_aliases(self, rule, aliases):
method add_ports_aliases (line 2431) | def add_ports_aliases(self, rule, aliases):
method generate_aliases (line 2439) | def generate_aliases(self, rule_filter=None):
method output_aliases (line 2484) | def output_aliases(aliases, ignored_aliases):
class PFSenseRuleFactory (line 2528) | class PFSenseRuleFactory(object):
method __init__ (line 2531) | def __init__(self, data, display_warnings=True):
method rule_interfaces_any (line 2536) | def rule_interfaces_any(self, rule_obj):
method rule_interfaces_ip_broadcast (line 2575) | def rule_interfaces_ip_broadcast(self, rule_obj):
method bridged_by_interfaces (line 2597) | def bridged_by_interfaces(self, routing_interfaces, dst):
method rule_interfaces (line 2613) | def rule_interfaces(self, rule_obj):
method generate_rule (line 2766) | def generate_rule(self, name, rule_obj, interfaces, last_name):
method aggregate_subrules (line 2937) | def aggregate_subrules(self, rule, interfaces, subrules, sub_interfaces):
method guess_rules (line 3041) | def guess_rules(self, rule_filter):
method generate_rules (line 3086) | def generate_rules(self, rule_filter=None):
method output_rules (line 3129) | def output_rules(self, rules, ignored_rules):
method output_src_nat_rules (line 3188) | def output_src_nat_rules(self, rules):
method output_dst_nat_rules (line 3229) | def output_dst_nat_rules(self, rules):
class PFSenseRuleSeparatorFactory (line 3263) | class PFSenseRuleSeparatorFactory(object):
method __init__ (line 3266) | def __init__(self, data):
method _find_first_separator_rule (line 3269) | def _find_first_separator_rule(self, separator):
method generate_rule_separators (line 3277) | def generate_rule_separators(self, rule_filter=None):
method output_rule_separators (line 3315) | def output_rule_separators(self, separators):
function _create_target_data (line 3337) | def _create_target_data(cached_data, target_name):
class LookupModule (line 3380) | class LookupModule(LookupBase):
method get_hostname (line 3383) | def get_hostname(self):
method get_definitions (line 3389) | def get_definitions(from_file):
method load_data (line 3393) | def load_data(self, from_file):
method _run (line 3412) | def _run(self, terms, variables, **kwargs):
method run (line 3477) | def run(self, terms, variables, **kwargs):
function unit_test_helper (line 3497) | def unit_test_helper(filename, pfname):
function main (line 3531) | def main():
FILE: plugins/module_utils/alias.py
class PFSenseAliasModule (line 54) | class PFSenseAliasModule(PFSenseModuleBase):
method get_argument_spec (line 62) | def get_argument_spec():
method __init__ (line 69) | def __init__(self, module, pfsense=None):
method _validate_params (line 78) | def _validate_params(self):
FILE: plugins/module_utils/arg_route.py
function p2o_cert (line 13) | def p2o_cert(self, name, params, obj):
function p2o_interface (line 17) | def p2o_interface(self, name, params, obj):
function p2o_interface_with_gwgroup (line 21) | def p2o_interface_with_gwgroup(self, name, params, obj):
function p2o_interface_without_virtual (line 25) | def p2o_interface_without_virtual(self, name, params, obj):
function p2o_port (line 29) | def p2o_port(self, name, params, obj):
function p2o_strip (line 33) | def p2o_strip(self, name, params, obj):
FILE: plugins/module_utils/arg_validate.py
function validate_cert (line 11) | def validate_cert(self, cert):
FILE: plugins/module_utils/default_gateway.py
class PFSenseDefaultGatewayModule (line 20) | class PFSenseDefaultGatewayModule(PFSenseModuleBase):
method get_argument_spec (line 24) | def get_argument_spec():
method __init__ (line 31) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 41) | def _params_to_obj(self):
method _validate_params (line 64) | def _validate_params(self):
method _create_target (line 88) | def _create_target(self):
method _gw2machine (line 100) | def _gw2machine(gateway):
method _gw2human (line 114) | def _gw2human(gateway):
method _get_params_to_remove (line 128) | def _get_params_to_remove():
method run (line 133) | def run(self, params):
method _update (line 145) | def _update(self):
method _get_obj_name (line 165) | def _get_obj_name(self):
method _log_fields (line 169) | def _log_fields(self, before=None):
FILE: plugins/module_utils/dhcp_server.py
class PFSenseDHCPServerModule (line 57) | class PFSenseDHCPServerModule(PFSenseModuleBase):
method get_argument_spec (line 61) | def get_argument_spec():
method __init__ (line 68) | def __init__(self, module, pfsense=None):
method _get_logical_interface (line 80) | def _get_logical_interface(self, interface):
method _is_valid_netif (line 99) | def _is_valid_netif(self, netif):
method _is_valid_macaddr (line 112) | def _is_valid_macaddr(self, macaddr):
method _params_to_obj (line 115) | def _params_to_obj(self):
method _validate_params (line 163) | def _validate_params(self):
method _get_params_to_remove (line 211) | def _get_params_to_remove(self):
method _create_target (line 218) | def _create_target(self):
method _find_target (line 222) | def _find_target(self):
method _get_obj_name (line 229) | def _get_obj_name(self):
method _log_fields (line 233) | def _log_fields(self, before=None):
method _update (line 297) | def _update(self):
method _pre_remove_target_elt (line 305) | def _pre_remove_target_elt(self):
FILE: plugins/module_utils/gateway.py
class PFSenseGatewayModule (line 34) | class PFSenseGatewayModule(PFSenseModuleBase):
method get_argument_spec (line 38) | def get_argument_spec():
method __init__ (line 45) | def __init__(self, module, pfsense=None):
method _check_gateway_groups (line 54) | def _check_gateway_groups(self):
method _check_routes (line 71) | def _check_routes(self):
method _check_subnet (line 83) | def _check_subnet(self):
method _params_to_obj (line 123) | def _params_to_obj(self):
method _validate_params (line 156) | def _validate_params(self):
method _get_params_to_remove (line 194) | def _get_params_to_remove():
method _update (line 201) | def _update(self):
method _get_obj_name (line 221) | def _get_obj_name(self):
method _log_fields (line 225) | def _log_fields(self, before=None):
FILE: plugins/module_utils/haproxy_backend.py
class PFSenseHaproxyBackendModule (line 32) | class PFSenseHaproxyBackendModule(PFSenseModuleBase):
method get_argument_spec (line 36) | def get_argument_spec():
method __init__ (line 43) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 57) | def _params_to_obj(self):
method _validate_params (line 82) | def _validate_params(self):
method _create_target (line 91) | def _create_target(self):
method _find_target (line 97) | def _find_target(self):
method _get_next_id (line 107) | def _get_next_id(self):
method _update (line 122) | def _update(self):
method _log_fields (line 130) | def _log_fields(self, before=None):
method _get_obj_name (line 170) | def _get_obj_name(self):
FILE: plugins/module_utils/haproxy_backend_server.py
class PFSenseHaproxyBackendServerModule (line 39) | class PFSenseHaproxyBackendServerModule(PFSenseModuleBase):
method get_argument_spec (line 43) | def get_argument_spec():
method __init__ (line 50) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 68) | def _params_to_obj(self):
method _validate_params (line 111) | def _validate_params(self):
method _create_target (line 146) | def _create_target(self):
method _find_backend (line 152) | def _find_backend(self, name):
method _find_target (line 162) | def _find_target(self):
method _get_params_to_remove (line 173) | def _get_params_to_remove():
method _get_next_id (line 179) | def _get_next_id(self):
method _update (line 194) | def _update(self):
method _get_ref_names (line 202) | def _get_ref_names(self, before):
method _get_obj_name (line 225) | def _get_obj_name(self):
method _log_fields (line 229) | def _log_fields(self, before=None):
FILE: plugins/module_utils/interface.py
class PFSenseInterfaceModule (line 50) | class PFSenseInterfaceModule(PFSenseModuleBase):
method get_argument_spec (line 54) | def get_argument_spec():
method __init__ (line 61) | def __init__(self, module, pfsense=None):
method _check_overlaps (line 75) | def _check_overlaps(self, ipfield, netfield):
method _params_to_obj (line 108) | def _params_to_obj(self):
method _validate_params (line 159) | def _validate_params(self):
method _copy_and_add_target (line 217) | def _copy_and_add_target(self):
method _copy_and_update_target (line 224) | def _copy_and_update_target(self):
method _create_target (line 238) | def _create_target(self):
method _get_interface_elt_by_port_and_display_name (line 257) | def _get_interface_elt_by_port_and_display_name(self, interface_port, ...
method _get_interface_elt_by_display_name (line 267) | def _get_interface_elt_by_display_name(self, name):
method _get_interface_display_name_by_port (line 277) | def _get_interface_display_name_by_port(self, interface_port):
method _get_interface_elt_by_port (line 288) | def _get_interface_elt_by_port(self, interface_port):
method _find_matching_interface (line 295) | def _find_matching_interface(self):
method _find_target (line 315) | def _find_target(self):
method _get_params_to_remove (line 320) | def _get_params_to_remove():
method _pre_remove_target_elt (line 325) | def _pre_remove_target_elt(self):
method _remove_all_rules (line 345) | def _remove_all_rules(self, interface):
method _remove_all_separators (line 385) | def _remove_all_separators(self, interface):
method _get_interface_list (line 404) | def _get_interface_list(self):
method _get_media_mode (line 464) | def _get_media_mode(self, interface):
method get_pre_update_cmds (line 481) | def get_pre_update_cmds(self):
method get_update_cmds (line 491) | def get_update_cmds(self):
method _pre_update (line 511) | def _pre_update(self):
method _update (line 515) | def _update(self):
method _get_obj_name (line 522) | def _get_obj_name(self):
method _log_fields (line 526) | def _log_fields(self, before=None):
method _log_update (line 575) | def _log_update(self, before):
FILE: plugins/module_utils/interface_group.py
class PFSenseInterfaceGroupModule (line 29) | class PFSenseInterfaceGroupModule(PFSenseModuleBase):
method get_argument_spec (line 33) | def get_argument_spec():
method __init__ (line 40) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 47) | def _params_to_obj(self):
method _validate_params (line 69) | def _validate_params(self):
method _remove_all_rules (line 90) | def _remove_all_rules(self, interface):
method _remove_all_separators (line 130) | def _remove_all_separators(self, interface):
method _update (line 150) | def _update(self):
method _log_fields (line 157) | def _log_fields(self, before=None):
FILE: plugins/module_utils/ipsec.py
function p2o_ipsec_interface (line 96) | def p2o_ipsec_interface(self, name, params, obj):
class PFSenseIpsecModule (line 110) | class PFSenseIpsecModule(PFSenseModuleBase):
method get_argument_spec (line 114) | def get_argument_spec():
method __init__ (line 121) | def __init__(self, module, pfsense=None):
method _create_target (line 134) | def _create_target(self):
method _find_free_ikeid (line 140) | def _find_free_ikeid(self):
method _find_target (line 155) | def _find_target(self):
method _get_params_to_remove (line 161) | def _get_params_to_remove(self):
method _pre_remove_target_elt (line 173) | def _pre_remove_target_elt(self):
method _remove_phases2 (line 177) | def _remove_phases2(self):
method _params_to_obj (line 194) | def _params_to_obj(self):
method _deprecated_params (line 231) | def _deprecated_params(self):
method _onward_params (line 238) | def _onward_params(self):
method _validate_params (line 250) | def _validate_params(self):
method _update (line 300) | def _update(self):
method _log_fields (line 307) | def _log_fields(self, before=None):
method _get_ref_names (line 402) | def _get_ref_names(self, before):
FILE: plugins/module_utils/ipsec_p2.py
class PFSenseIpsecP2Module (line 74) | class PFSenseIpsecP2Module(PFSenseModuleBase):
method get_argument_spec (line 78) | def get_argument_spec():
method __init__ (line 85) | def __init__(self, module, pfsense=None):
method _check_for_duplicate_phase2 (line 103) | def _check_for_duplicate_phase2(self, phase2):
method _id_to_phase2 (line 129) | def _id_to_phase2(self, name, phase2, address, param_name):
method _params_to_obj (line 166) | def _params_to_obj(self):
method _validate_params (line 207) | def _validate_params(self):
method _copy_and_add_target (line 243) | def _copy_and_add_target(self):
method _copy_and_update_target (line 250) | def _copy_and_update_target(self):
method _create_target (line 267) | def _create_target(self):
method _find_free_reqid (line 275) | def _find_free_reqid(self):
method _find_target (line 292) | def _find_target(self):
method _remove_deleted_ipsec_params (line 308) | def _remove_deleted_ipsec_params(self):
method _remove_extra_deleted_ipsec_params (line 323) | def _remove_extra_deleted_ipsec_params(self, name):
method _sync_encryptions (line 343) | def _sync_encryptions(self, phase2_elt):
method _sync_hashes (line 393) | def _sync_hashes(self, phase2_elt):
method _update (line 432) | def _update(self):
method _get_obj_name (line 438) | def _get_obj_name(self):
method _log_fields (line 442) | def _log_fields(self, before=None):
method _prepare_log_address (line 514) | def _prepare_log_address(self, before, param, name):
method _prepare_log_encryptions (line 528) | def _prepare_log_encryptions(before, before_elt):
method _prepare_log_hashes (line 548) | def _prepare_log_hashes(before, before_elt):
FILE: plugins/module_utils/ipsec_proposal.py
class PFSenseIpsecProposalModule (line 32) | class PFSenseIpsecProposalModule(PFSenseModuleBase):
method get_argument_spec (line 36) | def get_argument_spec():
method __init__ (line 43) | def __init__(self, module, pfsense=None):
method _onward_params (line 56) | def _onward_params(self):
method _params_to_obj (line 61) | def _params_to_obj(self):
method _validate_params (line 85) | def _validate_params(self):
method _copy_and_update_target (line 123) | def _copy_and_update_target():
method _create_target (line 127) | def _create_target(self):
method _find_target (line 131) | def _find_target(self):
method _update (line 152) | def _update(self):
method _get_obj_name (line 159) | def _get_obj_name(self):
method _log_fields (line 163) | def _log_fields(self, before=None):
method _log_fields_delete (line 174) | def _log_fields_delete(self):
FILE: plugins/module_utils/module_base.py
function merge_dicts (line 19) | def merge_dicts(a: dict, b: dict, path=None):
function move_dict_key (line 34) | def move_dict_key(obj, src, dst):
class PFSenseModuleBase (line 48) | class PFSenseModuleBase(object):
method get_argument_spec (line 56) | def get_argument_spec():
method __init__ (line 63) | def __init__(self, module, pfsense=None, package=None, name=None, root...
method _get_ansible_param (line 169) | def _get_ansible_param(self, obj, name, fname=None, force=False, exclu...
method _get_ansible_param_bool (line 185) | def _get_ansible_param_bool(self, obj, name, fname=None, force=False, ...
method _params_to_obj (line 204) | def _params_to_obj(self, obj=None):
method _validate_params (line 253) | def _validate_params(self):
method _deprecated_params (line 266) | def _deprecated_params(self):
method _onward_params (line 270) | def _onward_params(self):
method _check_deprecated_params (line 274) | def _check_deprecated_params(self):
method _check_onward_params (line 284) | def _check_onward_params(self):
method _copy_and_add_target (line 297) | def _copy_and_add_target(self):
method _copy_and_update_target (line 308) | def _copy_and_update_target(self):
method _create_target (line 319) | def _create_target(self):
method _find_this_element_index (line 333) | def _find_this_element_index(self):
method _find_last_element_index (line 336) | def _find_last_element_index(self):
method _find_target (line 342) | def _find_target(self):
method _get_params_to_remove (line 355) | def _get_params_to_remove(self):
method _remove_deleted_params (line 367) | def _remove_deleted_params(self):
method _remove_target_elt (line 377) | def _remove_target_elt(self):
method _add (line 385) | def _add(self):
method commit_changes (line 403) | def commit_changes(self):
method _post_remove_target_elt (line 420) | def _post_remove_target_elt(self):
method _pre_remove_target_elt (line 424) | def _pre_remove_target_elt(self):
method _remove (line 428) | def _remove(self):
method _pre_update (line 438) | def _pre_update():
method _update (line 442) | def _update(self):
method _run_post (line 449) | def _run_post(self):
method run (line 454) | def run(self, params):
method _log_create (line 476) | def _log_create(self):
method _log_delete (line 482) | def _log_delete(self):
method _log_fields (line 488) | def _log_fields(self, before=None):
method _log_fields_delete (line 503) | def _log_fields_delete():
method _log_update (line 507) | def _log_update(self, before):
method _get_obj_name (line 513) | def _get_obj_name(self):
method _get_module_name (line 517) | def _get_module_name(self, strip=False):
method format_cli_field (line 523) | def format_cli_field(self, after, field, log_none=False, add_comma=Tru...
method format_updated_cli_field (line 551) | def format_updated_cli_field(self, after, before, field, log_none=True...
method fvalue_idem (line 577) | def fvalue_idem(value):
method fvalue_bool (line 582) | def fvalue_bool(value):
FILE: plugins/module_utils/module_config_base.py
class PFSenseModuleConfigBase (line 14) | class PFSenseModuleConfigBase(PFSenseModuleBase):
method __init__ (line 20) | def __init__(self, module, pfsense=None, package=None, name=None, root...
method _params_to_obj (line 31) | def _params_to_obj(self):
method _find_target (line 45) | def _find_target(self):
method _get_obj_name (line 52) | def _get_obj_name(self):
FILE: plugins/module_utils/nat_outbound.py
function p2o_after (line 54) | def p2o_after(self, name, params, obj):
function p2o_before (line 58) | def p2o_before(self, name, params, obj):
function p2o_ipprotocol (line 62) | def p2o_ipprotocol(self, name, params, obj):
function p2o_protocol (line 68) | def p2o_protocol(self, name, params, obj):
class PFSenseNatOutboundModule (line 82) | class PFSenseNatOutboundModule(PFSenseModuleBase):
method get_argument_spec (line 86) | def get_argument_spec():
method __init__ (line 93) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 107) | def _params_to_obj(self):
method _parse_address (line 127) | def _parse_address(self, obj, field, field_port, allow_self, target):
method _parse_ports (line 180) | def _parse_ports(self, obj, ports, field_port, param):
method _parse_translated_address (line 196) | def _parse_translated_address(self, obj):
method _validate_params (line 234) | def _validate_params(self):
method _copy_and_add_target (line 252) | def _copy_and_add_target(self):
method _copy_and_update_target (line 258) | def _copy_and_update_target(self):
method _create_target (line 314) | def _create_target(self):
method _find_first_rule_idx (line 319) | def _find_first_rule_idx(self):
method _find_rule_by_descr (line 328) | def _find_rule_by_descr(self, descr):
method _find_target (line 338) | def _find_target(self):
method _get_expected_rule_position (line 348) | def _get_expected_rule_position(self):
method _get_expected_rule_xml_index (line 368) | def _get_expected_rule_xml_index(self):
method _get_params_to_remove (line 394) | def _get_params_to_remove():
method _get_rule_position (line 398) | def _get_rule_position(self, descr=None, fail=True):
method _insert (line 408) | def _insert(self, rule_elt):
method _update_rule_position (line 413) | def _update_rule_position(self, rule_elt):
method _update (line 429) | def _update(self):
method fvalue_protocol (line 438) | def fvalue_protocol(value):
method fvalue_ipprotocol (line 446) | def fvalue_ipprotocol(value):
method _log_fields (line 453) | def _log_fields(self, before=None):
method _obj_address_to_log_field (line 497) | def _obj_address_to_log_field(self, rule, addr, target, port):
method _obj_to_log_fields (line 518) | def _obj_to_log_fields(self, rule):
FILE: plugins/module_utils/nat_port_forward.py
class PFSenseNatPortForwardModule (line 36) | class PFSenseNatPortForwardModule(PFSenseModuleBase):
method get_argument_spec (line 40) | def get_argument_spec():
method __init__ (line 47) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 68) | def _params_to_obj(self):
method _parse_target_address (line 110) | def _parse_target_address(self, obj):
method _validate_params (line 144) | def _validate_params(self):
method _copy_and_add_target (line 159) | def _copy_and_add_target(self):
method _copy_and_update_target (line 166) | def _copy_and_update_target(self):
method _create_associated_rule (line 184) | def _create_associated_rule(self):
method _create_target (line 206) | def _create_target(self):
method _delete_associated_rule (line 211) | def _delete_associated_rule(self, ruleid, interface=None):
method _find_rule_by_descr (line 229) | def _find_rule_by_descr(self, descr):
method _find_target (line 239) | def _find_target(self):
method _get_expected_rule_position (line 249) | def _get_expected_rule_position(self):
method _get_expected_rule_xml_index (line 269) | def _get_expected_rule_xml_index(self):
method _get_params_to_remove (line 295) | def _get_params_to_remove():
method _get_rule_position (line 299) | def _get_rule_position(self, descr=None, fail=True):
method _insert (line 309) | def _insert(self, rule_elt):
method _pre_remove_target_elt (line 314) | def _pre_remove_target_elt(self):
method _set_associated_rule (line 320) | def _set_associated_rule(self, before=None):
method _update_rule_position (line 337) | def _update_rule_position(self, rule_elt):
method _update (line 355) | def _update(self):
method _get_obj_name (line 363) | def _get_obj_name(self):
method fassociate (line 368) | def fassociate(value):
method fnatreflection (line 379) | def fnatreflection(value):
method fprotocol (line 387) | def fprotocol(value):
method _log_fields (line 394) | def _log_fields(self, before=None):
method _obj_address_to_log_field (line 439) | def _obj_address_to_log_field(rule, addr):
method _obj_to_log_fields (line 455) | def _obj_to_log_fields(self, rule):
FILE: plugins/module_utils/openvpn_client.py
class PFSenseOpenVPNClientModule (line 87) | class PFSenseOpenVPNClientModule(PFSenseModuleBase):
method __init__ (line 93) | def __init__(self, module, pfsense=None):
method _get_digest_name (line 107) | def _get_digest_name(self, digest: str):
method _params_to_obj (line 113) | def _params_to_obj(self):
method _validate_params (line 182) | def _validate_params(self):
method _nextvpnid (line 222) | def _nextvpnid(self):
method _find_openvpn_client (line 232) | def _find_openvpn_client(self, value, field='description'):
method _find_last_openvpn_idx (line 242) | def _find_last_openvpn_idx(self):
method _copy_and_update_target (line 248) | def _copy_and_update_target(self):
method _create_target (line 258) | def _create_target(self):
method _find_target (line 270) | def _find_target(self):
method _remove_target_elt (line 286) | def _remove_target_elt(self):
method _remove (line 294) | def _remove(self):
method _update (line 301) | def _update(self):
method _get_obj_name (line 308) | def _get_obj_name(self):
method _log_fields (line 312) | def _log_fields(self, before=None):
FILE: plugins/module_utils/openvpn_override.py
class PFSenseOpenVPNOverrideModule (line 52) | class PFSenseOpenVPNOverrideModule(PFSenseModuleBase):
method get_argument_spec (line 56) | def get_argument_spec():
method __init__ (line 63) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 73) | def _params_to_obj(self):
method _validate_params (line 118) | def _validate_params(self):
method _find_openvpn_csc (line 144) | def _find_openvpn_csc(self, value, field='common_name'):
method _find_last_openvpn_idx (line 154) | def _find_last_openvpn_idx(self):
method _copy_and_update_target (line 160) | def _copy_and_update_target(self):
method _create_target (line 176) | def _create_target(self):
method _find_target (line 185) | def _find_target(self):
method _get_params_to_remove (line 190) | def _get_params_to_remove(self):
method _remove_target_elt (line 197) | def _remove_target_elt(self):
method _remove (line 205) | def _remove(self):
method _update (line 212) | def _update(self):
method _get_obj_name (line 219) | def _get_obj_name(self):
method _log_fields (line 223) | def _log_fields(self, before=None):
FILE: plugins/module_utils/openvpn_server.py
class PFSenseOpenVPNServerModule (line 101) | class PFSenseOpenVPNServerModule(PFSenseModuleBase):
method get_argument_spec (line 105) | def get_argument_spec():
method __init__ (line 112) | def __init__(self, module, pfsense=None):
method _get_digest_name (line 126) | def _get_digest_name(self, digest: str):
method _params_to_obj (line 132) | def _params_to_obj(self):
method _validate_params (line 231) | def _validate_params(self):
method _openvpn_port_used (line 273) | def _openvpn_port_used(self, protocol, interface, port, vpnid=0):
method _nextvpnid (line 298) | def _nextvpnid(self):
method _find_openvpn_server (line 308) | def _find_openvpn_server(self, value, field='description'):
method _find_last_openvpn_idx (line 318) | def _find_last_openvpn_idx(self):
method _get_params_to_remove (line 324) | def _get_params_to_remove(self):
method _copy_and_update_target (line 333) | def _copy_and_update_target(self):
method _create_target (line 346) | def _create_target(self):
method _find_target (line 359) | def _find_target(self):
method _pre_remove_target_elt (line 378) | def _pre_remove_target_elt(self):
method _update (line 389) | def _update(self):
method _get_obj_name (line 399) | def _get_obj_name(self):
method _log_fields (line 403) | def _log_fields(self, before=None):
FILE: plugins/module_utils/pfsense.py
function xml_find (line 32) | def xml_find(node, elt):
class PFSenseModule (line 40) | class PFSenseModule(object):
method __init__ (line 43) | def __init__(self, module, config='/cf/conf/config.xml'):
method _scrub (line 68) | def _scrub(self):
method get_interface_by_display_name (line 73) | def get_interface_by_display_name(self, name):
method get_interface_by_port (line 81) | def get_interface_by_port(self, name):
method get_interface_display_name (line 88) | def get_interface_display_name(self, interface_id, return_none=False):
method get_interface_elt (line 110) | def get_interface_elt(self, interface_id):
method get_interface_port (line 117) | def get_interface_port(self, interface_id):
method get_interface_port_by_display_name (line 124) | def get_interface_port_by_display_name(self, name):
method get_interfaces_networks (line 132) | def get_interfaces_networks(self):
method is_interface_port (line 152) | def is_interface_port(self, interface_port):
method is_interface_display_name (line 160) | def is_interface_display_name(self, name):
method is_interface_group (line 169) | def is_interface_group(self, name):
method parse_interface (line 180) | def parse_interface(self, interface, fail=True, with_virtual=True, wit...
method is_ipv4_address (line 201) | def is_ipv4_address(address):
method is_ipv6_address (line 211) | def is_ipv6_address(address):
method is_ipv4_network (line 221) | def is_ipv4_network(address, strict=True):
method is_ipv6_network (line 231) | def is_ipv6_network(address, strict=True):
method is_ip_network (line 240) | def is_ip_network(self, address, strict=True):
method is_within_local_networks (line 244) | def is_within_local_networks(self, address):
method parse_ip_network (line 263) | def parse_ip_network(address, strict=True, returns_ip=True):
method parse_address (line 279) | def parse_address(self, param, allow_self=True):
method parse_port (line 328) | def parse_port(self, src_ports, ret):
method check_name (line 343) | def check_name(self, name, objtype):
method check_ip_address (line 370) | def check_ip_address(self, address, ipprotocol, objtype, allow_network...
method validate_openvpn_tunnel_network (line 391) | def validate_openvpn_tunnel_network(self, network, ipproto):
method validate_string (line 409) | def validate_string(self, name, objtype):
method addr_normalize (line 416) | def addr_normalize(addr):
method new_element (line 435) | def new_element(tag, text='\n\t\t\t'):
method get_element (line 443) | def get_element(self, node, root_elt=None, create_node=False):
method get_elements (line 456) | def get_elements(self, node, root_elt=None):
method get_index (line 462) | def get_index(self, elt, root_elt=None):
method find_elt (line 468) | def find_elt(self, node, search_text, search_field='descr', root_elt=N...
method find_elt_xpath (line 473) | def find_elt_xpath(self, search_xpath, root_elt=None, multiple_ok=False):
method remove_deleted_param_from_elt (line 489) | def remove_deleted_param_from_elt(elt, param, params):
method is_ipsec_enabled (line 499) | def is_ipsec_enabled(self):
method is_openvpn_enabled (line 509) | def is_openvpn_enabled(self):
method find_ipsec_phase1 (line 519) | def find_ipsec_phase1(self, field_value, field='descr'):
method rule_match_interface (line 532) | def rule_match_interface(rule_elt, interface, floating):
method get_interface_rules_count (line 544) | def get_interface_rules_count(self, interface, floating):
method get_rule_position (line 554) | def get_rule_position(self, descr, interface, floating, first=True):
method copy_dict_to_element (line 571) | def copy_dict_to_element(self, src, top_elt, sub=0, prev_elt=None):
method array_to_php (line 668) | def array_to_php(src, php_name):
method dict_to_php (line 675) | def dict_to_php(src, php_name):
method element_to_dict (line 686) | def element_to_dict(src_elt):
method config_get_path (line 703) | def config_get_path(self, name, default=None):
method get_refid (line 711) | def get_refid(self, node, name):
method get_caref (line 719) | def get_caref(self, name):
method get_certref (line 727) | def get_certref(self, name):
method get_crlref (line 731) | def get_crlref(self, name):
method get_username (line 736) | def get_username():
method find_alias (line 747) | def find_alias(self, name, aliastype=None):
method is_ip_or_alias (line 754) | def is_ip_or_alias(self, address):
method is_gateway_group (line 769) | def is_gateway_group(self, gwgroup):
method is_port_or_alias (line 773) | def is_port_or_alias(self, port):
method is_virtual_ip (line 785) | def is_virtual_ip(self, addr):
method get_virtual_ip_interface (line 795) | def get_virtual_ip_interface(self, vip):
method find_queue (line 813) | def find_queue(self, name, interface=None, enabled=False):
method find_limiter (line 844) | def find_limiter(self, name, enabled=False):
method find_vlan (line 862) | def find_vlan(self, interface, tag):
method _create_gw_elt (line 874) | def _create_gw_elt(self, name, interface_id, protocol):
method find_gateway_elt (line 884) | def find_gateway_elt(self, name, interface=None, protocol=None, dhcp=F...
method find_gateway_group_elt (line 928) | def find_gateway_group_elt(self, name, protocol='inet'):
method find_active_gateways (line 954) | def find_active_gateways(self):
method find_ca_elt (line 980) | def find_ca_elt(self, ca, search_field='descr'):
method find_cert_elt (line 984) | def find_cert_elt(self, cert, search_field='descr'):
method find_crl_elt (line 988) | def find_crl_elt(self, crl, search_field='descr'):
method find_schedule_elt (line 992) | def find_schedule_elt(self, name):
method uniqid (line 997) | def uniqid(prefix='', more_entropy=False):
method phpshell (line 1004) | def phpshell(self, command, debug=True):
method php (line 1013) | def php(self, command):
method write_config (line 1030) | def write_config(self, descr='Updated by ansible pfsense module'):
method get_version (line 1059) | def get_version():
method is_ce_version (line 1069) | def is_ce_version(version=None):
method is_version (line 1077) | def is_version(self, version, or_more=True):
method is_at_least_2_5_2 (line 1105) | def is_at_least_2_5_2(self):
method is_at_least_2_5_0 (line 1109) | def is_at_least_2_5_0(self):
method apply_ipsec_changes (line 1113) | def apply_ipsec_changes(self):
FILE: plugins/module_utils/route.py
class PFSenseRouteModule (line 23) | class PFSenseRouteModule(PFSenseModuleBase):
method get_argument_spec (line 27) | def get_argument_spec():
method __init__ (line 34) | def __init__(self, module, pfsense=None):
method _expand_alias (line 48) | def _expand_alias(self, networks):
method _params_to_obj (line 64) | def _params_to_obj(self):
method _validate_params (line 99) | def _validate_params(self):
method _create_target (line 120) | def _create_target(self):
method _find_target (line 124) | def _find_target(self):
method _get_params_to_remove (line 132) | def _get_params_to_remove():
method _update (line 139) | def _update(self):
method _get_obj_name (line 165) | def _get_obj_name(self):
method _log_fields (line 169) | def _log_fields(self, before=None):
FILE: plugins/module_utils/rule.py
class PFSenseRuleModule (line 58) | class PFSenseRuleModule(PFSenseModuleBase):
method get_argument_spec (line 62) | def get_argument_spec():
method __init__ (line 69) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 93) | def _params_to_obj(self):
method _parse_floating_interfaces (line 155) | def _parse_floating_interfaces(self, interfaces):
method _validate_params (line 166) | def _validate_params(self):
method _adjust_separators (line 262) | def _adjust_separators(self, start_idx, add=True, before=False):
method _check_tracker (line 294) | def _check_tracker(self):
method _copy_and_add_target (line 309) | def _copy_and_add_target(self):
method _copy_and_update_target (line 325) | def _copy_and_update_target(self):
method _create_target (line 358) | def _create_target(self):
method _find_matching_rule (line 362) | def _find_matching_rule(self):
method _find_rule (line 389) | def _find_rule(self, value, field='descr'):
method _find_target (line 399) | def _find_target(self):
method _get_expected_rule_position (line 408) | def _get_expected_rule_position(self):
method _get_expected_rule_xml_index (line 428) | def _get_expected_rule_xml_index(self):
method _get_first_rule_xml_index (line 459) | def _get_first_rule_xml_index(self):
method _get_last_rule_xml_index (line 468) | def _get_last_rule_xml_index(self):
method _get_first_deny_rule_xml_index (line 478) | def _get_first_deny_rule_xml_index(self):
method _get_params_to_remove (line 491) | def _get_params_to_remove():
method _get_rule_position (line 495) | def _get_rule_position(self, descr=None, fail=True, first=True):
method _insert (line 505) | def _insert(self, rule_elt):
method _match_interface (line 513) | def _match_interface(self, rule_elt):
method _update_rule_position (line 517) | def _update_rule_position(self, rule_elt):
method _pre_remove_target_elt (line 536) | def _pre_remove_target_elt(self):
method _rule_element_to_dict (line 542) | def _rule_element_to_dict(self):
method _update (line 557) | def _update(self):
method _get_obj_name (line 565) | def _get_obj_name(self):
method _interface_name (line 569) | def _interface_name(self):
method _log_fields (line 577) | def _log_fields(self, before=None):
method _obj_address_to_log_field (line 638) | def _obj_address_to_log_field(self, rule, addr):
method _obj_to_log_fields (line 671) | def _obj_to_log_fields(self, rule):
FILE: plugins/module_utils/rule_separator.py
class PFSenseRuleSeparatorModule (line 25) | class PFSenseRuleSeparatorModule(PFSenseModuleBase):
method get_argument_spec (line 29) | def get_argument_spec():
method __init__ (line 36) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 57) | def _params_to_obj(self):
method _create_target (line 89) | def _create_target(self):
method _copy_and_add_target (line 93) | def _copy_and_add_target(self):
method _find_target (line 99) | def _find_target(self):
method _get_expected_separator_position (line 108) | def _get_expected_separator_position(self):
method _get_rule_position (line 125) | def _get_rule_position(self, descr):
method _get_separator_position (line 132) | def _get_separator_position(self):
method _post_remove_target_elt (line 139) | def _post_remove_target_elt(self):
method _recompute_separators_tag (line 143) | def _recompute_separators_tag(self):
method _update (line 157) | def _update(self):
method _get_obj_name (line 165) | def _get_obj_name(self):
method _log_fields (line 169) | def _log_fields(self, before=None):
FILE: plugins/module_utils/vlan.py
class PFSenseVlanModule (line 19) | class PFSenseVlanModule(PFSenseModuleBase):
method get_argument_spec (line 23) | def get_argument_spec():
method __init__ (line 30) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 80) | def _params_to_obj(self):
method _validate_params (line 105) | def _validate_params(self):
method _cmd_create (line 130) | def _cmd_create(self):
method _copy_and_add_target (line 151) | def _copy_and_add_target(self):
method _copy_and_update_target (line 156) | def _copy_and_update_target(self):
method _create_target (line 166) | def _create_target(self):
method _find_target (line 170) | def _find_target(self):
method _pre_remove_target_elt (line 174) | def _pre_remove_target_elt(self):
method get_update_cmds (line 185) | def get_update_cmds(self):
method _update (line 194) | def _update(self):
method _get_obj_name (line 201) | def _get_obj_name(self):
method _log_fields (line 205) | def _log_fields(self, before=None):
FILE: plugins/modules/pfsense_aggregate.py
class PFSenseModuleAggregate (line 653) | class PFSenseModuleAggregate(object):
method __init__ (line 656) | def __init__(self, module):
method _update (line 668) | def _update(self):
method _parse_floating_interfaces (line 699) | def _parse_floating_interfaces(self, interfaces):
method want_rule (line 708) | def want_rule(self, rule_elt, rules, name_field='name'):
method want_rule_separator (line 752) | def want_rule_separator(self, separator_elt, rule_separators):
method want_alias (line 771) | def want_alias(self, alias_elt, aliases):
method want_interface (line 791) | def want_interface(interface_elt, interfaces):
method want_vlan (line 807) | def want_vlan(vlan_elt, vlans):
method is_filtered (line 820) | def is_filtered(interface_filter, params):
method run_rules (line 835) | def run_rules(self):
method run_nat_outbounds_rules (line 919) | def run_nat_outbounds_rules(self):
method run_nat_port_forwards_rules (line 958) | def run_nat_port_forwards_rules(self):
method run_aliases (line 997) | def run_aliases(self):
method run_interfaces (line 1021) | def run_interfaces(self):
method run_rule_separators (line 1047) | def run_rule_separators(self):
method run_vlans (line 1087) | def run_vlans(self):
method commit_changes (line 1112) | def commit_changes(self):
function main (line 1140) | def main():
FILE: plugins/modules/pfsense_alias.py
function main (line 90) | def main():
FILE: plugins/modules/pfsense_authserver_ldap.py
class PFSenseAuthserverLDAPModule (line 201) | class PFSenseAuthserverLDAPModule(PFSenseModuleBase):
method get_argument_spec (line 209) | def get_argument_spec():
method __init__ (line 213) | def __init__(self, module, pfsense=None):
method _validate_params (line 220) | def _validate_params(self):
method _params_to_obj (line 226) | def _params_to_obj(self):
method _find_target (line 292) | def _find_target(self):
method _update (line 304) | def _update(self):
function main (line 309) | def main():
FILE: plugins/modules/pfsense_authserver_radius.py
class PFSenseAuthserverRADIUSModule (line 106) | class PFSenseAuthserverRADIUSModule(PFSenseModuleBase):
method get_argument_spec (line 110) | def get_argument_spec():
method __init__ (line 114) | def __init__(self, module, pfsense=None):
method _validate_params (line 123) | def _validate_params(self):
method _params_to_obj (line 129) | def _params_to_obj(self):
method _find_target (line 152) | def _find_target(self):
method _find_this_index (line 161) | def _find_this_index(self):
method _create_target (line 164) | def _create_target(self):
method _copy_and_add_target (line 170) | def _copy_and_add_target(self):
method _get_obj_name (line 182) | def _get_obj_name(self):
method _log_fields (line 186) | def _log_fields(self, before=None):
function main (line 192) | def main():
FILE: plugins/modules/pfsense_ca.py
class PFSenseCAModule (line 224) | class PFSenseCAModule(PFSenseModuleBase):
method get_argument_spec (line 228) | def get_argument_spec():
method __init__ (line 232) | def __init__(self, module, pfsense=None):
method _validate_params (line 247) | def _validate_params(self):
method _params_to_obj (line 302) | def _params_to_obj(self):
method _find_crl_for_ca (line 332) | def _find_crl_for_ca(self, caref):
method _find_crl_by_name (line 341) | def _find_crl_by_name(self, crlname):
method _find_crl_by_refid (line 350) | def _find_crl_by_refid(self, crlrefid):
method _copy_and_add_target (line 359) | def _copy_and_add_target(self):
method _copy_and_update_target (line 374) | def _copy_and_update_target(self):
method _update (line 421) | def _update(self):
method _pre_remove_target_elt (line 501) | def _pre_remove_target_elt(self):
function main (line 514) | def main():
FILE: plugins/modules/pfsense_cert.py
class PFSenseCertModule (line 197) | class PFSenseCertModule(PFSenseModuleBase):
method get_argument_spec (line 201) | def get_argument_spec():
method __init__ (line 208) | def __init__(self, module, pfsense=None):
method _validate_params (line 215) | def _validate_params(self):
method _params_to_obj (line 256) | def _params_to_obj(self):
method _find_ca (line 286) | def _find_ca(self, caref):
method _copy_and_add_target (line 301) | def _copy_and_add_target(self):
method _copy_and_update_target (line 310) | def _copy_and_update_target(self):
method _get_obj_name (line 324) | def _get_obj_name(self):
method _log_fields (line 328) | def _log_fields(self, before=None):
method _update (line 340) | def _update(self):
method _pre_remove_target_elt (line 429) | def _pre_remove_target_elt(self):
function main (line 438) | def main():
FILE: plugins/modules/pfsense_default_gateway.py
function main (line 77) | def main():
FILE: plugins/modules/pfsense_dhcp_server.py
function main (line 194) | def main():
FILE: plugins/modules/pfsense_dhcp_static.py
class PFSenseDHCPStaticModule (line 210) | class PFSenseDHCPStaticModule(PFSenseModuleBase):
method get_argument_spec (line 214) | def get_argument_spec():
method __init__ (line 221) | def __init__(self, module, pfsense=None):
method _validate_params (line 231) | def _validate_params(self):
method _params_to_obj (line 255) | def _params_to_obj(self):
method _is_valid_netif (line 288) | def _is_valid_netif(self, netif):
method _find_staticmaps (line 301) | def _find_staticmaps(self, netif=None):
method _find_target (line 322) | def _find_target(self):
method _create_target (line 337) | def _create_target(self):
method _copy_and_add_target (line 341) | def _copy_and_add_target(self):
method _get_params_to_remove (line 348) | def _get_params_to_remove():
method _get_obj_name (line 355) | def _get_obj_name(self):
method _log_fields (line 359) | def _log_fields(self, before=None):
method _update (line 375) | def _update(self):
method _pre_remove_target_elt (line 385) | def _pre_remove_target_elt(self):
function main (line 395) | def main():
FILE: plugins/modules/pfsense_dns_resolver.py
class PFSenseDNSResolverModule (line 388) | class PFSenseDNSResolverModule(PFSenseModuleBase):
method get_argument_spec (line 392) | def get_argument_spec():
method __init__ (line 399) | def __init__(self, module, pfsense=None):
method _get_interface_name (line 416) | def _get_interface_name(self, iface: str):
method _params_to_obj (line 429) | def _params_to_obj(self):
method _validate_params (line 493) | def _validate_params(self):
method _create_target (line 513) | def _create_target(self):
method _find_target (line 517) | def _find_target(self):
method _get_params_to_remove (line 521) | def _get_params_to_remove(self):
method _update (line 532) | def _update(self):
method _get_obj_name (line 548) | def _get_obj_name(self):
method _log_fields (line 552) | def _log_fields(self, before=None):
function main (line 589) | def main():
FILE: plugins/modules/pfsense_gateway.py
function main (line 119) | def main():
FILE: plugins/modules/pfsense_gateway_group.py
function p2o_members (line 113) | def p2o_members(self, name, params, obj):
class PFSenseGatewayGroupModule (line 134) | class PFSenseGatewayGroupModule(PFSenseModuleBase):
method get_argument_spec (line 142) | def get_argument_spec():
method __init__ (line 146) | def __init__(self, module, pfsense=None):
function main (line 151) | def main():
FILE: plugins/modules/pfsense_group.py
class PFSenseGroupModule (line 93) | class PFSenseGroupModule(PFSenseModuleBase):
method __init__ (line 96) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 105) | def _params_to_obj(self):
method _validate_params (line 123) | def _validate_params(self):
method _nextgid (line 126) | def _nextgid(self):
method _copy_and_add_target (line 136) | def _copy_and_add_target(self):
method _copy_and_update_target (line 153) | def _copy_and_update_target(self):
method _create_target (line 162) | def _create_target(self):
method _find_target (line 166) | def _find_target(self):
method _find_group_by_gid (line 169) | def _find_group_by_gid(self, gid):
method _find_this_group_index (line 172) | def _find_this_group_index(self):
method _find_last_group_index (line 175) | def _find_last_group_index(self):
method _update (line 181) | def _update(self):
method _get_obj_name (line 190) | def _get_obj_name(self):
method _log_fields (line 194) | def _log_fields(self, before=None):
function main (line 200) | def main():
FILE: plugins/modules/pfsense_haproxy_backend.py
function main (line 129) | def main():
FILE: plugins/modules/pfsense_haproxy_backend_server.py
function main (line 146) | def main():
FILE: plugins/modules/pfsense_interface.py
function main (line 151) | def main():
FILE: plugins/modules/pfsense_interface_group.py
function main (line 85) | def main():
FILE: plugins/modules/pfsense_ipsec.py
function main (line 210) | def main():
FILE: plugins/modules/pfsense_ipsec_aggregate.py
class PFSenseModuleIpsecAggregate (line 440) | class PFSenseModuleIpsecAggregate(object):
method __init__ (line 443) | def __init__(self, module):
method _update (line 450) | def _update(self):
method want_ipsec (line 457) | def want_ipsec(ipsec_elt, ipsecs):
method proposal_elt_to_params (line 471) | def proposal_elt_to_params(self, ipsec_elt, proposal_elt):
method want_ipsec_proposal (line 495) | def want_ipsec_proposal(self, ipsec_elt, proposal_elt, proposals):
method want_ipsec_phase2 (line 515) | def want_ipsec_phase2(self, phase2_elt, phases2):
method run_ipsecs (line 539) | def run_ipsecs(self):
method run_ipsec_proposals (line 565) | def run_ipsec_proposals(self):
method run_ipsec_p2s (line 598) | def run_ipsec_p2s(self):
method commit_changes (line 625) | def commit_changes(self):
function main (line 646) | def main():
FILE: plugins/modules/pfsense_ipsec_p2.py
function main (line 191) | def main():
FILE: plugins/modules/pfsense_ipsec_proposal.py
function main (line 108) | def main():
FILE: plugins/modules/pfsense_log_settings.py
class PFSenseLogSettingsModule (line 258) | class PFSenseLogSettingsModule(PFSenseModuleBase):
method get_argument_spec (line 262) | def get_argument_spec():
method __init__ (line 269) | def __init__(self, module, pfsense=None):
method _params_to_obj (line 284) | def _params_to_obj(self):
method _is_interface_ip_or_descr (line 322) | def _is_interface_ip_or_descr(self, address):
method _get_interface_by_ip_or_display_name (line 339) | def _get_interface_by_ip_or_display_name(self, address):
method _get_source_ip_interface (line 356) | def _get_source_ip_interface(self, address):
method _validate_syslog_server (line 367) | def _validate_syslog_server(self, hostname, name):
method _validate_params (line 393) | def _validate_params(self):
method _remove_deleted_params (line 440) | def _remove_deleted_params(self):
method run (line 454) | def run(self, params):
method _update (line 462) | def _update(self):
method _get_obj_name (line 492) | def _get_obj_name():
method _log_fields (line 496) | def _log_fields(self, before=None):
function main (line 510) | def main():
FILE: plugins/modules/pfsense_nat_outbound.py
function main (line 134) | def main():
FILE: plugins/modules/pfsense_nat_port_forward.py
function main (line 129) | def main():
FILE: plugins/modules/pfsense_openvpn_client.py
function main (line 264) | def main():
FILE: plugins/modules/pfsense_openvpn_override.py
function main (line 142) | def main():
FILE: plugins/modules/pfsense_openvpn_server.py
function main (line 369) | def main():
FILE: plugins/modules/pfsense_phpshell.py
class PFSensePHPShellModule (line 83) | class PFSensePHPShellModule(PFSenseModuleBase):
method get_argument_spec (line 87) | def get_argument_spec():
method __init__ (line 94) | def __init__(self, module, pfsense=None):
method run (line 102) | def run(self, params):
function main (line 116) | def main():
FILE: plugins/modules/pfsense_rewrite_config.py
class PFSenseRewriteConfigModule (line 42) | class PFSenseRewriteConfigModule(PFSenseModuleBase):
method get_argument_spec (line 46) | def get_argument_spec():
method __init__ (line 53) | def __init__(self, module, pfsense=None):
method commit_changes (line 61) | def commit_changes(self):
method _update (line 70) | def _update(self):
function main (line 76) | def main():
FILE: plugins/modules/pfsense_route.py
function main (line 74) | def main():
FILE: plugins/modules/pfsense_rule.py
function main (line 182) | def main():
FILE: plugins/modules/pfsense_rule_separator.py
function main (line 81) | def main():
FILE: plugins/modules/pfsense_setup.py
function p2o_dnslocalhost (line 262) | def p2o_dnslocalhost(self, name, params, obj):
function p2o_network_list_to_space_separated (line 272) | def p2o_network_list_to_space_separated(self, name, params, obj):
function p2o_webguicss (line 280) | def p2o_webguicss(self, name, params, obj):
function validate_webguicss (line 289) | def validate_webguicss(self, webguicss):
class PFSenseSetupModule (line 334) | class PFSenseSetupModule(PFSenseModuleConfigBase):
method get_argument_spec (line 338) | def get_argument_spec():
method __init__ (line 345) | def __init__(self, module, pfsense=None):
method _dns_params_to_obj (line 354) | def _dns_params_to_obj(self, params, obj):
method _params_to_obj (line 411) | def _params_to_obj(self):
method _validate_hostname (line 417) | def _validate_hostname(self, hostname, name, strict=False):
method _validate_params (line 429) | def _validate_params(self):
method _validate_timezone (line 517) | def _validate_timezone(self, timezone):
method _get_params_to_remove (line 526) | def _get_params_to_remove(self):
method _update (line 535) | def _update(self):
method _get_obj_name (line 590) | def _get_obj_name():
method _log_fields (line 594) | def _log_fields(self, before=None):
method _prepare_dns_log (line 638) | def _prepare_dns_log(obj):
function main (line 683) | def main():
FILE: plugins/modules/pfsense_shellcmd.py
class PFSenseShellcmdModule (line 92) | class PFSenseShellcmdModule(PFSenseModuleBase):
method get_argument_spec (line 100) | def get_argument_spec():
method __init__ (line 104) | def __init__(self, module, pfsense=None):
method _find_target (line 111) | def _find_target(self):
function main (line 126) | def main():
FILE: plugins/modules/pfsense_user.py
function parse_groups (line 112) | def parse_groups(self, name, params, obj):
function p2o_ssh_pub_key (line 118) | def p2o_ssh_pub_key(self, name, params, obj):
function validate_password (line 124) | def validate_password(self, password):
class PFSenseUserModule (line 165) | class PFSenseUserModule(PFSenseModuleBase):
method get_argument_spec (line 173) | def get_argument_spec():
method __init__ (line 177) | def __init__(self, module, pfsense=None):
method _find_group_elt (line 187) | def _find_group_elt(self, name):
method _find_group_names_for_uid (line 190) | def _find_group_names_for_uid(self, uid):
method _nextuid (line 196) | def _nextuid(self):
method _format_diff_priv (line 202) | def _format_diff_priv(self, priv):
method _copy_and_add_target (line 208) | def _copy_and_add_target(self):
method _copy_and_update_target (line 223) | def _copy_and_update_target(self):
method _update_groups (line 240) | def _update_groups(self):
method _remove_deleted_disabled_param (line 284) | def _remove_deleted_disabled_param(self):
method _update (line 296) | def _update(self):
method _pre_remove_target_elt (line 302) | def _pre_remove_target_elt(self):
function main (line 324) | def main():
FILE: plugins/modules/pfsense_vlan.py
function main (line 76) | def main():
FILE: tests/unit/plugins/lookup/test_pfsense.py
function ordered_dump (line 14) | def ordered_dump(data, dumper_cls=yaml.Dumper):
class TestPFSenseLookup (line 27) | class TestPFSenseLookup(ModuleTestCase):
method __init__ (line 31) | def __init__(self, *args, **kwargs):
method setUp (line 39) | def setUp(self):
method tearDown (line 53) | def tearDown(self):
method build_definitions (line 59) | def build_definitions(self):
method save_definitions (line 88) | def save_definitions(self, filename='test_definitions.yml'):
method run_rules (line 93) | def run_rules(self):
method assert_get_rule (line 98) | def assert_get_rule(self, rule_name, count=1):
method assert_rule_not_found (line 114) | def assert_rule_not_found(self, rule_name):
method add_missing_fields (line 121) | def add_missing_fields(expected_rule, rule):
method correct_aliases (line 134) | def correct_aliases(expected_rule):
method compare_rules (line 144) | def compare_rules(self, expected_rule, rule):
method gen_rule (line 152) | def gen_rule(self, src, dst, interface, action):
method test_basic_generation (line 193) | def test_basic_generation(self):
FILE: tests/unit/plugins/module_utils/test_pfsense.py
class TestPFSense (line 12) | class TestPFSense(TestPFSenseModule):
method __init__ (line 14) | def __init__(self, *args, **kwargs):
method setUp (line 17) | def setUp(self):
method tearDown (line 23) | def tearDown(self):
method my_get_version (line 27) | def my_get_version(self):
method test_is_version (line 30) | def test_is_version(self):
method test_is_at_least_2_5_0 (line 50) | def test_is_at_least_2_5_0(self):
FILE: tests/unit/plugins/modules/pfsense_module.py
function load_fixture (line 26) | def load_fixture(name):
class TestPFSenseModule (line 44) | class TestPFSenseModule(ModuleTestCase):
method __init__ (line 48) | def __init__(self, *args, **kwargs):
method setUp (line 55) | def setUp(self):
method tearDown (line 87) | def tearDown(self):
method get_args_fields (line 106) | def get_args_fields(self):
method get_target_elt (line 113) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 117) | def check_target_elt(self, obj, target_elt):
method check_target_elt_direct (line 121) | def check_target_elt_direct(self, target_elt, expected_elt_string):
method args_from_var (line 126) | def args_from_var(self, var, state='present', **kwargs):
method execute_module (line 142) | def execute_module(self, failed=False, changed=False, commands=None, s...
method do_module_test (line 164) | def do_module_test(self, obj, command=None, changed=True, failed=False...
method failed (line 200) | def failed(self):
method changed (line 208) | def changed(self, changed=False):
method strip_commands (line 233) | def strip_commands(self, commands):
method strip_params (line 237) | def strip_params(self, params):
method get_config_file (line 241) | def get_config_file(self):
method load_fixtures (line 245) | def load_fixtures(self):
method load_xml_result (line 249) | def load_xml_result(self):
method find_xml_tag (line 256) | def find_xml_tag(parent_tag, elt_filter):
method assert_xml_elt_value (line 273) | def assert_xml_elt_value(self, parent_tag_name, elt_filter, elt_name, ...
method assert_xml_elt_dict (line 286) | def assert_xml_elt_dict(self, parent_tag_name, elt_filter, elts):
method assert_has_xml_tag (line 300) | def assert_has_xml_tag(self, parent_tag_name, elt_filter, absent=False):
method assert_find_xml_elt (line 314) | def assert_find_xml_elt(self, tag, elt_name):
method assert_not_find_xml_elt (line 320) | def assert_not_find_xml_elt(self, tag, elt_name):
method assert_xml_elt_equal (line 326) | def assert_xml_elt_equal(self, tag, elt_name, elt_value):
method assert_xml_elt_match (line 343) | def assert_xml_elt_match(self, tag, elt_name, elt_regex):
method assert_xml_elt_is_none_or_empty (line 355) | def assert_xml_elt_is_none_or_empty(self, tag, elt_name):
method assert_list_xml_elt_equal (line 363) | def assert_list_xml_elt_equal(self, tag, elt_name, elt_value):
method unalias_interface (line 382) | def unalias_interface(interface, physical=False):
method check_param_equal (line 398) | def check_param_equal(self, params, target_elt, param, default=None, x...
method check_param_bool (line 415) | def check_param_bool(self, params, target_elt, param, default=False, v...
method check_value_equal (line 435) | def check_value_equal(self, target_elt, xml_field, value, empty=True):
method check_param_equal_or_not_find (line 445) | def check_param_equal_or_not_find(self, params, target_elt, param, xml...
method check_param_equal_or_present (line 459) | def check_param_equal_or_present(self, params, target_elt, param, xml_...
method check_list_param_equal (line 468) | def check_list_param_equal(self, params, target_elt, param, default=No...
method check_list_param_equal_or_not_find (line 485) | def check_list_param_equal_or_not_find(self, params, target_elt, param...
FILE: tests/unit/plugins/modules/test_pfsense_aggregate.py
class TestPFSenseAggregateModule (line 18) | class TestPFSenseAggregateModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method assert_find_alias (line 26) | def assert_find_alias(self, alias):
method assert_not_find_alias (line 37) | def assert_not_find_alias(self, alias):
method assert_find_rule (line 48) | def assert_find_rule(self, rule, interface):
method assert_not_find_rule (line 59) | def assert_not_find_rule(self, rule, interface):
method assert_find_rule_separator (line 70) | def assert_find_rule_separator(self, separator, interface):
method assert_not_find_rule_separator (line 90) | def assert_not_find_rule_separator(self, separator, interface):
method assert_find_vlan (line 110) | def assert_find_vlan(self, interface, vlan_id):
method assert_not_find_vlan (line 124) | def assert_not_find_vlan(self, interface, vlan_id):
method test_aggregate_aliases (line 142) | def test_aggregate_aliases(self):
method test_aggregate_aliases_checkmode (line 170) | def test_aggregate_aliases_checkmode(self):
method test_aggregate_aliases_purge (line 194) | def test_aggregate_aliases_purge(self):
method test_aggregate_rules (line 224) | def test_aggregate_rules(self):
method test_aggregate_rules_purge (line 245) | def test_aggregate_rules_purge(self):
method test_aggregate_separators (line 266) | def test_aggregate_separators(self):
method test_aggregate_separators_purge (line 291) | def test_aggregate_separators_purge(self):
method test_aggregate_nat_outbound (line 321) | def test_aggregate_nat_outbound(self):
method test_aggregate_vlans (line 338) | def test_aggregate_vlans(self):
method test_aggregate_vlans_with_purge (line 363) | def test_aggregate_vlans_with_purge(self):
FILE: tests/unit/plugins/modules/test_pfsense_alias.py
class TestPFSenseAliasModule (line 21) | class TestPFSenseAliasModule(TestPFSenseModule):
method __init__ (line 25) | def __init__(self, *args, **kwargs):
method do_alias_creation_test (line 35) | def do_alias_creation_test(self, alias, set_after=None, unset_after=No...
method do_alias_deletion_test (line 53) | def do_alias_deletion_test(self, alias, command=None):
method do_alias_update_noop_test (line 63) | def do_alias_update_noop_test(self, alias):
method do_alias_update_field (line 73) | def do_alias_update_field(self, alias, set_after=None, command=None, *...
method test_host_create (line 93) | def test_host_create(self):
method test_host_delete (line 99) | def test_host_delete(self):
method test_host_update_noop (line 105) | def test_host_update_noop(self):
method test_host_update_ip (line 110) | def test_host_update_ip(self):
method test_host_update_descr (line 116) | def test_host_update_descr(self):
method test_port_create (line 125) | def test_port_create(self):
method test_port_delete (line 131) | def test_port_delete(self):
method test_port_update_noop (line 137) | def test_port_update_noop(self):
method test_port_update_port (line 142) | def test_port_update_port(self):
method test_port_update_descr (line 148) | def test_port_update_descr(self):
method test_network_create (line 157) | def test_network_create(self):
method test_network_delete (line 163) | def test_network_delete(self):
method test_network_update_noop (line 169) | def test_network_update_noop(self):
method test_network_update_network (line 174) | def test_network_update_network(self):
method test_network_update_descr (line 180) | def test_network_update_descr(self):
method test_urltable_create (line 189) | def test_urltable_create(self):
method test_urltable_create_url (line 195) | def test_urltable_create_url(self):
method test_urltable_create_exclusive (line 201) | def test_urltable_create_exclusive(self):
method test_urltable_delete (line 207) | def test_urltable_delete(self):
method test_urltable_update_noop (line 214) | def test_urltable_update_noop(self):
method test_urltable_update_url (line 220) | def test_urltable_update_url(self):
method test_urltable_update_descr (line 227) | def test_urltable_update_descr(self):
method test_urltable_update_freq (line 234) | def test_urltable_update_freq(self):
method test_urltable_ports_create (line 241) | def test_urltable_ports_create(self):
method test_create_alias_duplicate (line 250) | def test_create_alias_duplicate(self):
method test_create_alias_invalid_name (line 255) | def test_create_alias_invalid_name(self):
method test_create_alias_invalid_name_interface (line 262) | def test_create_alias_invalid_name_interface(self):
method test_create_alias_invalid_updatefreq (line 267) | def test_create_alias_invalid_updatefreq(self):
method test_create_alias_without_type (line 272) | def test_create_alias_without_type(self):
method test_create_alias_without_address (line 277) | def test_create_alias_without_address(self):
method test_create_alias_invalid_details (line 282) | def test_create_alias_invalid_details(self):
method test_create_alias_invalid_details2 (line 287) | def test_create_alias_invalid_details2(self):
method test_delete_inexistent_alias (line 292) | def test_delete_inexistent_alias(self):
method test_check_mode (line 302) | def test_check_mode(self):
method test_urltable_required_if (line 314) | def test_urltable_required_if(self):
method test_urltable_ports_required_if (line 320) | def test_urltable_ports_required_if(self):
FILE: tests/unit/plugins/modules/test_pfsense_alias_null.py
class TestPFSenseAliasNullModule (line 21) | class TestPFSenseAliasNullModule(TestPFSenseModule):
method __init__ (line 25) | def __init__(self, *args, **kwargs):
method do_alias_creation_test (line 35) | def do_alias_creation_test(self, alias, failed=False, msg='', command=...
method test_host_create (line 51) | def test_host_create(self):
FILE: tests/unit/plugins/modules/test_pfsense_authserver_ldap.py
class TestPFSenseAuthserverLDAPModule (line 17) | class TestPFSenseAuthserverLDAPModule(TestPFSenseModule):
method __init__ (line 21) | def __init__(self, *args, **kwargs):
method runTest (line 27) | def runTest():
method get_target_elt (line 31) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 42) | def check_target_elt(self, obj, target_elt):
method test_authserver_create (line 70) | def test_authserver_create(self):
method test_authserver_delete (line 75) | def test_authserver_delete(self):
method test_authserver_update_noop (line 80) | def test_authserver_update_noop(self):
method test_authserver_update_host (line 85) | def test_authserver_update_host(self):
method test_authserver_disable_allow_unauthenticated (line 90) | def test_authserver_disable_allow_unauthenticated(self):
method test_create_authserver_invalid_timeout (line 98) | def test_create_authserver_invalid_timeout(self):
method test_delete_inexistent_authserver (line 103) | def test_delete_inexistent_authserver(self):
FILE: tests/unit/plugins/modules/test_pfsense_authserver_radius.py
class TestPFSenseAuthserverRADIUSModule (line 17) | class TestPFSenseAuthserverRADIUSModule(TestPFSenseModule):
method __init__ (line 21) | def __init__(self, *args, **kwargs):
method runTest (line 27) | def runTest():
method get_target_elt (line 31) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 42) | def check_target_elt(self, obj, target_elt):
method test_authserver_create (line 60) | def test_authserver_create(self):
method test_authserver_delete (line 65) | def test_authserver_delete(self):
method test_authserver_update_noop (line 70) | def test_authserver_update_noop(self):
method test_authserver_update_host (line 75) | def test_authserver_update_host(self):
method test_create_authserver_invalid_timeout (line 83) | def test_create_authserver_invalid_timeout(self):
method test_delete_inexistent_authserver (line 88) | def test_delete_inexistent_authserver(self):
FILE: tests/unit/plugins/modules/test_pfsense_ca.py
class TestPFSenseCAModule (line 58) | class TestPFSenseCAModule(TestPFSenseModule):
method __init__ (line 62) | def __init__(self, *args, **kwargs):
method setUp (line 67) | def setUp(self):
method runTest (line 77) | def runTest():
method get_target_elt (line 81) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 92) | def check_target_elt(self, obj, target_elt):
method test_ca_create (line 106) | def test_ca_create(self):
method test_ca_add_crl (line 111) | def test_ca_add_crl(self):
method test_ca_change_crl (line 116) | def test_ca_change_crl(self):
method test_ca_delete (line 121) | def test_ca_delete(self):
method test_ca_update_noop (line 126) | def test_ca_update_noop(self):
method test_ca_update_serial (line 131) | def test_ca_update_serial(self):
method test_ca_update_trust (line 136) | def test_ca_update_trust(self):
method test_create_ca_invalid_serial (line 144) | def test_create_ca_invalid_serial(self):
method test_delete_nonexistent_ca (line 149) | def test_delete_nonexistent_ca(self):
FILE: tests/unit/plugins/modules/test_pfsense_cert.py
class TestPFSenseCertModule (line 87) | class TestPFSenseCertModule(TestPFSenseModule):
method __init__ (line 91) | def __init__(self, *args, **kwargs):
method runTest (line 97) | def runTest():
method get_target_elt (line 101) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 112) | def check_target_elt(self, obj, target_elt):
method test_cert_create (line 123) | def test_cert_create(self):
method test_cert_import (line 128) | def test_cert_import(self):
method test_cert_delete (line 133) | def test_cert_delete(self):
method test_cert_update_noop (line 138) | def test_cert_update_noop(self):
method test_add_invalid_key (line 146) | def test_add_invalid_key(self):
FILE: tests/unit/plugins/modules/test_pfsense_dhcp_server.py
class TestPFSenseDHCPServerModule (line 18) | class TestPFSenseDHCPServerModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method check_target_elt (line 27) | def check_target_elt(self, obj, target_elt, target_idx=-1):
method get_target_elt (line 56) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_dhcp_server_create (line 64) | def test_dhcp_server_create(self):
method test_dhcp_server_update (line 85) | def test_dhcp_server_update(self):
method test_dhcp_server_update_disable_denyunknown (line 99) | def test_dhcp_server_update_disable_denyunknown(self):
method test_dhcp_server_delete (line 113) | def test_dhcp_server_delete(self):
method test_dhcp_server_create_invalid_interface (line 119) | def test_dhcp_server_create_invalid_interface(self):
method test_dhcp_server_create_invalid_range (line 124) | def test_dhcp_server_create_invalid_range(self):
method test_dhcp_server_create_with_options (line 130) | def test_dhcp_server_create_with_options(self):
FILE: tests/unit/plugins/modules/test_pfsense_dhcp_static.py
class TestPFSenseDHCPStaticModule (line 18) | class TestPFSenseDHCPStaticModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method check_target_elt (line 27) | def check_target_elt(self, obj, target_elt, target_idx=-1):
method get_target_elt (line 47) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_dhcp_static_create (line 76) | def test_dhcp_static_create(self):
method test_dhcp_static_create_empty (line 84) | def test_dhcp_static_create_empty(self):
method test_dhcp_static_create_display (line 92) | def test_dhcp_static_create_display(self):
method test_dhcp_static_create_arp_table_static_entry (line 100) | def test_dhcp_static_create_arp_table_static_entry(self):
method test_dhcp_static_create_wrong_subnet (line 108) | def test_dhcp_static_create_wrong_subnet(self):
method test_dhcp_static_create_no_netif (line 113) | def test_dhcp_static_create_no_netif(self):
method test_dhcp_static_create_ifgroup (line 118) | def test_dhcp_static_create_ifgroup(self):
method test_dhcp_static_create_invalid_macaddr (line 123) | def test_dhcp_static_create_invalid_macaddr(self):
method test_dhcp_static_delete_macaddr (line 131) | def test_dhcp_static_delete_macaddr(self):
method test_dhcp_static_delete_name (line 136) | def test_dhcp_static_delete_name(self):
FILE: tests/unit/plugins/modules/test_pfsense_dns_resolver.py
class TestPFSenseDNSResolverModule (line 14) | class TestPFSenseDNSResolverModule(TestPFSenseModule):
method __init__ (line 18) | def __init__(self, *args, **kwargs):
method setUp (line 23) | def setUp(self):
method check_target_elt (line 32) | def check_target_elt(self, obj, target_elt, target_idx=-1):
method get_target_elt (line 69) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_dns_resolver_init (line 76) | def test_dns_resolver_init(self):
method test_dns_resolver_change (line 90) | def test_dns_resolver_change(self):
method test_dns_resolver_noop (line 100) | def test_dns_resolver_noop(self):
method test_dns_resolver_domainoverrides_forward_tls_upstream (line 105) | def test_dns_resolver_domainoverrides_forward_tls_upstream(self):
FILE: tests/unit/plugins/modules/test_pfsense_gateway.py
class TestPFSenseGatewayModule (line 18) | class TestPFSenseGatewayModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method check_target_elt (line 27) | def check_target_elt(self, obj, target_elt):
method get_target_elt (line 44) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_gateway_create (line 58) | def test_gateway_create(self):
method test_gateway_create_with_params (line 64) | def test_gateway_create_with_params(self):
method test_gateway_create_ipv6 (line 70) | def test_gateway_create_ipv6(self):
method test_gateway_create_in_vip (line 76) | def test_gateway_create_in_vip(self):
method test_gateway_create_invalid_name (line 82) | def test_gateway_create_invalid_name(self):
method test_gateway_create_invalid_interface (line 89) | def test_gateway_create_invalid_interface(self):
method test_gateway_create_nonlocal (line 95) | def test_gateway_create_nonlocal(self):
method test_gateway_create_invalid_ip (line 101) | def test_gateway_create_invalid_ip(self):
method test_gateway_create_invalid_ip2 (line 107) | def test_gateway_create_invalid_ip2(self):
method test_gateway_create_invalid_ip3 (line 113) | def test_gateway_create_invalid_ip3(self):
method test_gateway_create_invalid_ip4 (line 119) | def test_gateway_create_invalid_ip4(self):
method test_gateway_create_invalid_monitor (line 125) | def test_gateway_create_invalid_monitor(self):
method test_gateway_create_invalid_ipv6 (line 131) | def test_gateway_create_invalid_ipv6(self):
method test_gateway_create_invalid_ipv6_2 (line 137) | def test_gateway_create_invalid_ipv6_2(self):
method test_gateway_create_invalid_ipv6_monitor (line 143) | def test_gateway_create_invalid_ipv6_monitor(self):
method test_gateway_create_invalid_weight (line 149) | def test_gateway_create_invalid_weight(self):
method test_gateway_update_noop (line 155) | def test_gateway_update_noop(self):
method test_gateway_update_dynamic (line 160) | def test_gateway_update_dynamic(self):
method test_gateway_update_dynamic2 (line 166) | def test_gateway_update_dynamic2(self):
method test_gateway_update_dynamic3 (line 172) | def test_gateway_update_dynamic3(self):
method test_gateway_update_dynamic4 (line 178) | def test_gateway_update_dynamic4(self):
method test_gateway_update_interface (line 184) | def test_gateway_update_interface(self):
method test_gateway_update_bools_and_monitor (line 190) | def test_gateway_update_bools_and_monitor(self):
method test_gateway_delete (line 196) | def test_gateway_delete(self):
method test_gateway_delete_static (line 202) | def test_gateway_delete_static(self):
method test_gateway_delete_default (line 208) | def test_gateway_delete_default(self):
method test_gateway_delete_in_group (line 214) | def test_gateway_delete_in_group(self):
method test_gateway_delete_in_route (line 220) | def test_gateway_delete_in_route(self):
FILE: tests/unit/plugins/modules/test_pfsense_haproxy_backend.py
class TestPFSenseHaproxyBackendModule (line 18) | class TestPFSenseHaproxyBackendModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_target_elt (line 30) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 45) | def check_target_elt(self, obj, target_elt, backend_id=100):
method test_haproxy_backend_create (line 94) | def test_haproxy_backend_create(self):
method test_haproxy_backend_create2 (line 100) | def test_haproxy_backend_create2(self):
method test_haproxy_backend_create_invalid_name (line 106) | def test_haproxy_backend_create_invalid_name(self):
method test_haproxy_backend_delete (line 112) | def test_haproxy_backend_delete(self):
method test_haproxy_backend_update_noop (line 118) | def test_haproxy_backend_update_noop(self):
method test_haproxy_backend_update_bools (line 125) | def test_haproxy_backend_update_bools(self):
FILE: tests/unit/plugins/modules/test_pfsense_haproxy_backend_server.py
class TestPFSenseHaproxyBackendServerModule (line 18) | class TestPFSenseHaproxyBackendServerModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_target_elt (line 30) | def get_target_elt(self, obj, absent=False, module_result=None):
method caref (line 56) | def caref(descr):
method crlref (line 65) | def crlref(descr):
method certref (line 74) | def certref(descr):
method idem (line 83) | def idem(descr):
method check_target_elt (line 87) | def check_target_elt(self, obj, target_elt, server_id):
method test_haproxy_backend_server_create (line 136) | def test_haproxy_backend_server_create(self):
method test_haproxy_backend_server_create2 (line 142) | def test_haproxy_backend_server_create2(self):
method test_haproxy_backend_server_create_invalid_backend (line 153) | def test_haproxy_backend_server_create_invalid_backend(self):
method test_haproxy_backend_server_create_invalid_name (line 159) | def test_haproxy_backend_server_create_invalid_name(self):
method test_haproxy_backend_server_delete (line 165) | def test_haproxy_backend_server_delete(self):
method test_haproxy_backend_server_update_noop (line 171) | def test_haproxy_backend_server_update_noop(self):
method test_haproxy_backend_server_update_frontend (line 176) | def test_haproxy_backend_server_update_frontend(self):
method test_haproxy_backend_server_update_certs (line 182) | def test_haproxy_backend_server_update_certs(self):
method test_haproxy_backend_server_update_certs2 (line 190) | def test_haproxy_backend_server_update_certs2(self):
method test_haproxy_backend_server_update_certs3 (line 198) | def test_haproxy_backend_server_update_certs3(self):
method test_haproxy_backend_server_invalid_ca (line 206) | def test_haproxy_backend_server_invalid_ca(self):
method test_haproxy_backend_server_invalid_crl (line 212) | def test_haproxy_backend_server_invalid_crl(self):
method test_haproxy_backend_server_invalid_cert (line 218) | def test_haproxy_backend_server_invalid_cert(self):
method test_haproxy_backend_server_invalid_frontend (line 224) | def test_haproxy_backend_server_invalid_frontend(self):
FILE: tests/unit/plugins/modules/test_pfsense_interface.py
class TestPFSenseInterfaceModule (line 18) | class TestPFSenseInterfaceModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method setUp (line 27) | def setUp(self):
method tearDown (line 47) | def tearDown(self):
method get_target_elt (line 56) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 63) | def check_target_elt(self, obj, target_elt):
method test_interface_create_no_address (line 134) | def test_interface_create_no_address(self):
method test_interface_create_by_descr (line 140) | def test_interface_create_by_descr(self):
method test_interface_create_static (line 146) | def test_interface_create_static(self):
method test_interface_create_static_ipv6 (line 152) | def test_interface_create_static_ipv6(self):
method test_interface_create_slaac (line 158) | def test_interface_create_slaac(self):
method test_interface_create_none_mac_mtu_mss (line 164) | def test_interface_create_none_mac_mtu_mss(self):
method test_interface_delete (line 170) | def test_interface_delete(self):
method test_interface_delete_lan (line 176) | def test_interface_delete_lan(self):
method test_interface_delete_fails (line 190) | def test_interface_delete_fails(self):
method test_interface_update_noop (line 196) | def test_interface_update_noop(self):
method test_interface_update_name (line 201) | def test_interface_update_name(self):
method test_interface_update_enable (line 207) | def test_interface_update_enable(self):
method test_interface_update_enable2 (line 213) | def test_interface_update_enable2(self):
method test_interface_update_mac (line 219) | def test_interface_update_mac(self):
method test_interface_update_blocks (line 226) | def test_interface_update_blocks(self):
method test_interface_error_used (line 233) | def test_interface_error_used(self):
method test_interface_error_gw (line 239) | def test_interface_error_gw(self):
method test_interface_error_if (line 246) | def test_interface_error_if(self):
method test_interface_error_eq (line 253) | def test_interface_error_eq(self):
method test_interface_error_overlaps1 (line 259) | def test_interface_error_overlaps1(self):
method test_interface_error_overlaps2 (line 265) | def test_interface_error_overlaps2(self):
method test_interface_error_inet6_eq (line 271) | def test_interface_error_inet6_eq(self):
method test_interface_error_inet6_overlaps1 (line 277) | def test_interface_error_inet6_overlaps1(self):
method test_interface_error_inet6_overlaps2 (line 283) | def test_interface_error_inet6_overlaps2(self):
method test_interface_delete_sub (line 289) | def test_interface_delete_sub(self):
method test_interface_error_not_uniq (line 295) | def test_interface_error_not_uniq(self):
FILE: tests/unit/plugins/modules/test_pfsense_interface_group.py
class TestPFSenseInterfaceGroupModule (line 19) | class TestPFSenseInterfaceGroupModule(TestPFSenseModule):
method __init__ (line 23) | def __init__(self, *args, **kwargs):
method setUp (line 28) | def setUp(self):
method tearDown (line 48) | def tearDown(self):
method get_target_elt (line 57) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 64) | def check_target_elt(self, obj, target_elt):
method test_interface_group_create (line 81) | def test_interface_group_create(self):
method test_interface_group_create_with_descr (line 87) | def test_interface_group_create_with_descr(self):
method test_interface_group_delete (line 93) | def test_interface_group_delete(self):
method test_interface_group_update_noop (line 99) | def test_interface_group_update_noop(self):
method test_interface_group_update_descr (line 104) | def test_interface_group_update_descr(self):
method test_interface_group_update_members (line 110) | def test_interface_group_update_members(self):
method test_interface_group_error_no_members (line 116) | def test_interface_group_error_no_members(self):
method test_interface_group_error_member_does_not_exist (line 122) | def test_interface_group_error_member_does_not_exist(self):
method test_interface_group_error_members_not_uniq (line 128) | def test_interface_group_error_members_not_uniq(self):
FILE: tests/unit/plugins/modules/test_pfsense_ipsec.py
class TestPFSenseIpsecModule (line 18) | class TestPFSenseIpsecModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_config_file (line 26) | def get_config_file(self):
method get_target_elt (line 34) | def get_target_elt(self, obj, absent=False, module_result=None):
method caref (line 42) | def caref(descr):
method certref (line 51) | def certref(descr):
method check_target_elt (line 59) | def check_target_elt(self, obj, target_elt):
method strip_commands (line 159) | def strip_commands(self, commands):
method test_ipsec_create_ikev2 (line 168) | def test_ipsec_create_ikev2(self):
method test_ipsec_create_ikev1 (line 180) | def test_ipsec_create_ikev1(self):
method test_ipsec_create_vip_descr (line 191) | def test_ipsec_create_vip_descr(self):
method test_ipsec_create_vip_subnet (line 203) | def test_ipsec_create_vip_subnet(self):
method test_ipsec_create_auto (line 214) | def test_ipsec_create_auto(self):
method test_ipsec_delete (line 225) | def test_ipsec_delete(self):
method test_ipsec_update_noop (line 231) | def test_ipsec_update_noop(self):
method test_ipsec_update_ike (line 238) | def test_ipsec_update_ike(self):
method test_ipsec_update_gw (line 246) | def test_ipsec_update_gw(self):
method test_ipsec_update_auth (line 254) | def test_ipsec_update_auth(self):
method test_ipsec_update_cert (line 264) | def test_ipsec_update_cert(self):
method test_ipsec_duplicate_gw (line 272) | def test_ipsec_duplicate_gw(self):
FILE: tests/unit/plugins/modules/test_pfsense_ipsec_aggregate.py
class TestPFSenseIpsecAggregateModule (line 20) | class TestPFSenseIpsecAggregateModule(TestPFSenseModule):
method __init__ (line 24) | def __init__(self, *args, **kwargs):
method get_config_file (line 27) | def get_config_file(self):
method assert_find_ipsec (line 32) | def assert_find_ipsec(self, ipsec):
method assert_not_find_ipsec (line 51) | def assert_not_find_ipsec(self, ipsec):
method strip_commands (line 70) | def strip_commands(self, commands):
method test_ipsec_aggregate_ipsecs (line 91) | def test_ipsec_aggregate_ipsecs(self, pfsense_version):
method test_ipsec_aggregate_ipsecs_purge (line 132) | def test_ipsec_aggregate_ipsecs_purge(self, pfsense_version):
method test_ipsec_aggregate_proposals (line 168) | def test_ipsec_aggregate_proposals(self, pfsense_version):
method test_ipsec_aggregate_proposals_purge (line 195) | def test_ipsec_aggregate_proposals_purge(self, pfsense_version):
method test_ipsec_aggregate_p2s (line 232) | def test_ipsec_aggregate_p2s(self):
method test_ipsec_aggregate_p2s_purge (line 262) | def test_ipsec_aggregate_p2s_purge(self):
FILE: tests/unit/plugins/modules/test_pfsense_ipsec_p2.py
class TestPFSenseIpsecP2Module (line 18) | class TestPFSenseIpsecP2Module(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_phase1_elt (line 30) | def get_phase1_elt(self, descr, absent=False):
method get_target_elt (line 36) | def get_target_elt(self, obj, absent=False, module_result=None):
method get_enc_elt (line 46) | def get_enc_elt(phase2_elt, enc_name):
method check_enc (line 55) | def check_enc(self, phase2, phase2_elt, enc_name, param_name):
method get_hash_elt (line 71) | def get_hash_elt(phase2_elt, hash_name):
method check_hash (line 80) | def check_hash(self, phase2, phase2_elt, hash_name, param_name):
method param_to_address (line 90) | def param_to_address(self, address):
method check_address (line 116) | def check_address(self, phase2, phase2_elt, elt_name, param_name):
method check_target_elt (line 138) | def check_target_elt(self, obj, target_elt):
method test_phase2_create_vti (line 192) | def test_phase2_create_vti(self):
method test_phase2_create_tunnel (line 201) | def test_phase2_create_tunnel(self):
method test_phase2_delete (line 210) | def test_phase2_delete(self):
method test_phase2_update_noop (line 216) | def test_phase2_update_noop(self):
method test_phase2_update_aes_len (line 223) | def test_phase2_update_aes_len(self):
method test_phase2_update_disable_aes (line 231) | def test_phase2_update_disable_aes(self):
method test_phase2_update_set_3des (line 239) | def test_phase2_update_set_3des(self):
method test_phase2_update_remove_3des (line 247) | def test_phase2_update_remove_3des(self):
method test_phase2_update_remove_sha256 (line 255) | def test_phase2_update_remove_sha256(self):
method test_phase2_update_change_address (line 263) | def test_phase2_update_change_address(self):
method test_phase2_update_set_nat (line 271) | def test_phase2_update_set_nat(self):
method test_phase2_update_remove_nat (line 279) | def test_phase2_update_remove_nat(self):
method test_phase2_inexistent_tunnel (line 287) | def test_phase2_inexistent_tunnel(self):
method test_phase2_no_encryption (line 295) | def test_phase2_no_encryption(self):
method test_phase2_no_hash (line 302) | def test_phase2_no_hash(self):
method test_phase2_vti_lan (line 309) | def test_phase2_vti_lan(self):
method test_phase2_vti_lan2 (line 316) | def test_phase2_vti_lan2(self):
method test_phase2_tunnel6_remote (line 323) | def test_phase2_tunnel6_remote(self):
method test_phase2_tunnel6_remote2 (line 331) | def test_phase2_tunnel6_remote2(self):
method test_phase2_tunnel6_local (line 339) | def test_phase2_tunnel6_local(self):
method test_phase2_tunnel_remote (line 347) | def test_phase2_tunnel_remote(self):
method test_phase2_tunnel_remote2 (line 355) | def test_phase2_tunnel_remote2(self):
method test_phase2_tunnel_local (line 363) | def test_phase2_tunnel_local(self):
method test_phase2_duplicate (line 371) | def test_phase2_duplicate(self):
FILE: tests/unit/plugins/modules/test_pfsense_ipsec_proposal.py
class TestPFSenseIpsecProposalModule (line 19) | class TestPFSenseIpsecProposalModule(TestPFSenseModule):
method __init__ (line 23) | def __init__(self, *args, **kwargs):
method get_config_file (line 27) | def get_config_file(self):
method get_target_elt (line 37) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 79) | def check_target_elt(self, obj, target_elt):
method strip_commands (line 84) | def strip_commands(self, commands):
method test_ipsec_proposal_create (line 94) | def test_ipsec_proposal_create(self, pfsense_version):
method test_ipsec_proposal_create_nokeylen (line 102) | def test_ipsec_proposal_create_nokeylen(self, pfsense_version):
method test_ipsec_proposal_delete (line 110) | def test_ipsec_proposal_delete(self, pfsense_version):
method test_ipsec_proposal_update_noop (line 118) | def test_ipsec_proposal_update_noop(self, pfsense_version):
method test_ipsec_proposal_wrong_keylen (line 124) | def test_ipsec_proposal_wrong_keylen(self):
method test_ipsec_proposal_wrong_tunnel (line 130) | def test_ipsec_proposal_wrong_tunnel(self):
method test_ipsec_proposal_wrong_encryption (line 136) | def test_ipsec_proposal_wrong_encryption(self):
FILE: tests/unit/plugins/modules/test_pfsense_log_settings.py
class TestPFSenseLogSettingsModule (line 18) | class TestPFSenseLogSettingsModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_target_elt (line 37) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 41) | def check_target_elt(self, obj, target_elt):
method test_syslog_logformat_rfc5424 (line 127) | def test_syslog_logformat_rfc5424(self):
method test_syslog_logformat_rfc3164 (line 133) | def test_syslog_logformat_rfc3164(self):
method test_syslog_logformat_invalid (line 139) | def test_syslog_logformat_invalid(self):
method test_syslog_reverse (line 145) | def test_syslog_reverse(self):
method test_syslog_reverse_true (line 151) | def test_syslog_reverse_true(self):
method test_syslog_nentries_valid (line 156) | def test_syslog_nentries_valid(self):
method test_syslog_nentries_valid2 (line 162) | def test_syslog_nentries_valid2(self):
method test_syslog_nentries_valid3 (line 168) | def test_syslog_nentries_valid3(self):
method test_syslog_nentries_invalid1 (line 174) | def test_syslog_nentries_invalid1(self):
method test_syslog_nentries_invalid2 (line 180) | def test_syslog_nentries_invalid2(self):
method test_syslog_nentries_invalid3 (line 186) | def test_syslog_nentries_invalid3(self):
method test_syslog_nologdefaultblock_false (line 192) | def test_syslog_nologdefaultblock_false(self):
method test_syslog_nologdefaultblock_true (line 197) | def test_syslog_nologdefaultblock_true(self):
method test_syslog_nologdefaultpass_false (line 203) | def test_syslog_nologdefaultpass_false(self):
method test_syslog_nologdefaultpass_true (line 210) | def test_syslog_nologdefaultpass_true(self):
method test_syslog_nologbogons_false (line 215) | def test_syslog_nologbogons_false(self):
method test_syslog_nologbogons_true (line 220) | def test_syslog_nologbogons_true(self):
method test_syslog_nologprivatenets_false (line 226) | def test_syslog_nologprivatenets_false(self):
method test_syslog_nologprivatenets_true (line 231) | def test_syslog_nologprivatenets_true(self):
method test_syslog_nolognginx_false (line 237) | def test_syslog_nolognginx_false(self):
method test_syslog_nolognginx_true (line 242) | def test_syslog_nolognginx_true(self):
method test_syslog_rawfilter_false (line 248) | def test_syslog_rawfilter_false(self):
method test_syslog_rawfilter_true (line 253) | def test_syslog_rawfilter_true(self):
method test_syslog_filterdescriptions_valid0 (line 259) | def test_syslog_filterdescriptions_valid0(self):
method test_syslog_filterdescriptions_valid1 (line 265) | def test_syslog_filterdescriptions_valid1(self):
method test_syslog_filterdescriptions_valid2 (line 270) | def test_syslog_filterdescriptions_valid2(self):
method test_syslog_filterdescriptions_invalid3 (line 276) | def test_syslog_filterdescriptions_invalid3(self):
method test_syslog_disablelocallogging_false (line 282) | def test_syslog_disablelocallogging_false(self):
method test_syslog_disablelocallogging_true (line 287) | def test_syslog_disablelocallogging_true(self):
method test_syslog_logfilesize_valid1 (line 293) | def test_syslog_logfilesize_valid1(self):
method test_syslog_logfilesize_valid2 (line 299) | def test_syslog_logfilesize_valid2(self):
method test_syslog_logfilesize_valid3 (line 305) | def test_syslog_logfilesize_valid3(self):
method test_syslog_logfilesize_invalid1 (line 311) | def test_syslog_logfilesize_invalid1(self):
method test_syslog_logfilesize_invalid2 (line 317) | def test_syslog_logfilesize_invalid2(self):
method test_syslog_logfilesize_invalid3 (line 323) | def test_syslog_logfilesize_invalid3(self):
method test_syslog_logfilesize_invalid4 (line 329) | def test_syslog_logfilesize_invalid4(self):
method test_syslog_logcompressiontype_valid_xz (line 335) | def test_syslog_logcompressiontype_valid_xz(self):
method test_syslog_logcompressiontype_valid_gzip (line 341) | def test_syslog_logcompressiontype_valid_gzip(self):
method test_syslog_rotatecount_valid0 (line 347) | def test_syslog_rotatecount_valid0(self):
method test_syslog_rotatecount_valid1 (line 353) | def test_syslog_rotatecount_valid1(self):
method test_syslog_rotatecount_valid2 (line 359) | def test_syslog_rotatecount_valid2(self):
method test_syslog_rotatecount_valid3 (line 365) | def test_syslog_rotatecount_valid3(self):
method test_syslog_rotatecount_invalid1 (line 371) | def test_syslog_rotatecount_invalid1(self):
method test_syslog_rotatecount_invalid2 (line 377) | def test_syslog_rotatecount_invalid2(self):
method test_syslog_enable_true (line 383) | def test_syslog_enable_true(self):
method test_syslog_enable_false (line 389) | def test_syslog_enable_false(self):
method test_syslog_ipproto_ipv4 (line 394) | def test_syslog_ipproto_ipv4(self):
method test_syslog_ipproto_ipv6 (line 400) | def test_syslog_ipproto_ipv6(self):
method test_syslog_sourceip_wan_ip (line 406) | def test_syslog_sourceip_wan_ip(self):
method test_syslog_sourceip_wan_descr (line 412) | def test_syslog_sourceip_wan_descr(self):
method test_syslog_sourceip_lan (line 418) | def test_syslog_sourceip_lan(self):
method test_syslog_sourceip_lo0 (line 424) | def test_syslog_sourceip_lo0(self):
method test_syslog_sourceip_descr (line 430) | def test_syslog_sourceip_descr(self):
method test_syslog_sourceip_valid_empty (line 436) | def test_syslog_sourceip_valid_empty(self):
method test_syslog_sourceip_valid_vip_ip (line 442) | def test_syslog_sourceip_valid_vip_ip(self):
method test_syslog_sourceip_invalid_vip (line 448) | def test_syslog_sourceip_invalid_vip(self):
method test_syslog_sourceip_invalid_opt4 (line 454) | def test_syslog_sourceip_invalid_opt4(self):
method test_syslog_remoteserver_hostname (line 460) | def test_syslog_remoteserver_hostname(self):
method test_syslog_remoteserver_fqdn (line 466) | def test_syslog_remoteserver_fqdn(self):
method test_syslog_remoteserver_fqdn_port (line 472) | def test_syslog_remoteserver_fqdn_port(self):
method test_syslog_remoteserver_ipv6 (line 478) | def test_syslog_remoteserver_ipv6(self):
method test_syslog_remoteserver_ipv6_port (line 484) | def test_syslog_remoteserver_ipv6_port(self):
method test_syslog_remoteserver_ipv4_invalid_port1 (line 490) | def test_syslog_remoteserver_ipv4_invalid_port1(self):
method test_syslog_remoteserver_ipv4_invalid_port2 (line 496) | def test_syslog_remoteserver_ipv4_invalid_port2(self):
method test_syslog_ipproto_invalid (line 502) | def test_syslog_ipproto_invalid(self):
method test_syslog_logall_true (line 508) | def test_syslog_logall_true(self):
method test_syslog_logall_false (line 514) | def test_syslog_logall_false(self):
method test_syslog_system_true (line 520) | def test_syslog_system_true(self):
method test_syslog_system_false (line 526) | def test_syslog_system_false(self):
method test_syslog_system_invalid_with_logall (line 532) | def test_syslog_system_invalid_with_logall(self):
method test_syslog_system_valid_with_logall (line 538) | def test_syslog_system_valid_with_logall(self):
method test_syslog_logfilter_true (line 544) | def test_syslog_logfilter_true(self):
method test_syslog_logfilter_false (line 550) | def test_syslog_logfilter_false(self):
method test_syslog_logfilter_invalid_with_logall (line 556) | def test_syslog_logfilter_invalid_with_logall(self):
method test_syslog_logfilter_valid_with_logall (line 562) | def test_syslog_logfilter_valid_with_logall(self):
method test_syslog_resolver_true (line 568) | def test_syslog_resolver_true(self):
method test_syslog_resolver_false (line 574) | def test_syslog_resolver_false(self):
method test_syslog_resolver_invalid_with_logall (line 580) | def test_syslog_resolver_invalid_with_logall(self):
method test_syslog_resolver_valid_with_logall (line 586) | def test_syslog_resolver_valid_with_logall(self):
method test_syslog_dhcp_true (line 592) | def test_syslog_dhcp_true(self):
method test_syslog_dhcp_false (line 598) | def test_syslog_dhcp_false(self):
method test_syslog_dhcp_invalid_with_logall (line 604) | def test_syslog_dhcp_invalid_with_logall(self):
method test_syslog_dhcp_valid_with_logall (line 610) | def test_syslog_dhcp_valid_with_logall(self):
method test_syslog_ppp_true (line 616) | def test_syslog_ppp_true(self):
method test_syslog_ppp_false (line 622) | def test_syslog_ppp_false(self):
method test_syslog_ppp_invalid_with_logall (line 628) | def test_syslog_ppp_invalid_with_logall(self):
method test_syslog_ppp_valid_with_logall (line 634) | def test_syslog_ppp_valid_with_logall(self):
method test_syslog_auth_true (line 640) | def test_syslog_auth_true(self):
method test_syslog_auth_false (line 646) | def test_syslog_auth_false(self):
method test_syslog_auth_invalid_with_logall (line 652) | def test_syslog_auth_invalid_with_logall(self):
method test_syslog_auth_valid_with_logall (line 658) | def test_syslog_auth_valid_with_logall(self):
method test_syslog_portalauth_true (line 664) | def test_syslog_portalauth_true(self):
method test_syslog_portalauth_false (line 670) | def test_syslog_portalauth_false(self):
method test_syslog_portalauth_invalid_with_logall (line 676) | def test_syslog_portalauth_invalid_with_logall(self):
method test_syslog_portalauth_valid_with_logall (line 682) | def test_syslog_portalauth_valid_with_logall(self):
method test_syslog_vpn_true (line 688) | def test_syslog_vpn_true(self):
method test_syslog_vpn_false (line 694) | def test_syslog_vpn_false(self):
method test_syslog_vpn_invalid_with_logall (line 700) | def test_syslog_vpn_invalid_with_logall(self):
method test_syslog_vpn_valid_with_logall (line 706) | def test_syslog_vpn_valid_with_logall(self):
method test_syslog_dpinger_true (line 712) | def test_syslog_dpinger_true(self):
method test_syslog_dpinger_false (line 718) | def test_syslog_dpinger_false(self):
method test_syslog_dpinger_invalid_with_logall (line 724) | def test_syslog_dpinger_invalid_with_logall(self):
method test_syslog_dpinger_valid_with_logall (line 730) | def test_syslog_dpinger_valid_with_logall(self):
method test_syslog_routing_true (line 736) | def test_syslog_routing_true(self):
method test_syslog_routing_false (line 742) | def test_syslog_routing_false(self):
method test_syslog_routing_invalid_with_logall (line 748) | def test_syslog_routing_invalid_with_logall(self):
method test_syslog_routing_valid_with_logall (line 754) | def test_syslog_routing_valid_with_logall(self):
method test_syslog_ntpd_true (line 760) | def test_syslog_ntpd_true(self):
method test_syslog_ntpd_false (line 766) | def test_syslog_ntpd_false(self):
method test_syslog_ntpd_invalid_with_logall (line 772) | def test_syslog_ntpd_invalid_with_logall(self):
method test_syslog_ntpd_valid_with_logall (line 778) | def test_syslog_ntpd_valid_with_logall(self):
method test_syslog_hostapd_true (line 784) | def test_syslog_hostapd_true(self):
method test_syslog_hostapd_false (line 790) | def test_syslog_hostapd_false(self):
method test_syslog_hostapd_invalid_with_logall (line 796) | def test_syslog_hostapd_invalid_with_logall(self):
method test_syslog_hostapd_valid_with_logall (line 802) | def test_syslog_hostapd_valid_with_logall(self):
FILE: tests/unit/plugins/modules/test_pfsense_nat_outbound.py
class TestPFSenseNatOutboundModule (line 19) | class TestPFSenseNatOutboundModule(TestPFSenseModule):
method __init__ (line 23) | def __init__(self, *args, **kwargs):
method is_ipv4_address (line 29) | def is_ipv4_address(address):
method parse_address (line 38) | def parse_address(self, name, addr, field, invert=False):
method reparse_network (line 71) | def reparse_network(value):
method check_addr (line 78) | def check_addr(self, params, target_elt, addr, field, port, invert=Fal...
method check_target_addr (line 90) | def check_target_addr(self, params, target_elt):
method md5 (line 106) | def md5(value):
method check_target_elt (line 111) | def check_target_elt(self, obj, target_elt, target_idx=-1):
method check_rule_idx (line 131) | def check_rule_idx(self, params, target_idx):
method get_target_elt (line 149) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_nat_outbound_create (line 164) | def test_nat_outbound_create(self):
method test_nat_outbound_create_aliases (line 170) | def test_nat_outbound_create_aliases(self):
method test_nat_outbound_create_address (line 179) | def test_nat_outbound_create_address(self):
method test_nat_outbound_create_address_net (line 185) | def test_nat_outbound_create_address_net(self):
method test_nat_outbound_create_networks (line 191) | def test_nat_outbound_create_networks(self):
method test_nat_outbound_ipprotocol (line 197) | def test_nat_outbound_ipprotocol(self):
method test_nat_outbound_protocol (line 203) | def test_nat_outbound_protocol(self):
method test_nat_outbound_create_networks_invert (line 209) | def test_nat_outbound_create_networks_invert(self):
method test_nat_outbound_create_interface_destination_network (line 215) | def test_nat_outbound_create_interface_destination_network(self):
method test_nat_outbound_create_interface_source_network (line 221) | def test_nat_outbound_create_interface_source_network(self):
method test_nat_outbound_create_top (line 227) | def test_nat_outbound_create_top(self):
method test_nat_outbound_create_after (line 233) | def test_nat_outbound_create_after(self):
method test_nat_outbound_create_before (line 239) | def test_nat_outbound_create_before(self):
method test_nat_outbound_create_with_sourcehashkey (line 245) | def test_nat_outbound_create_with_sourcehashkey(self):
method test_nat_outbound_create_with_sourcehashkey_str (line 251) | def test_nat_outbound_create_with_sourcehashkey_str(self):
method test_nat_outbound_update_noop (line 257) | def test_nat_outbound_update_noop(self):
method test_nat_outbound_update_bottom (line 262) | def test_nat_outbound_update_bottom(self):
method test_nat_outbound_update_top (line 268) | def test_nat_outbound_update_top(self):
method test_nat_outbound_update_source (line 274) | def test_nat_outbound_update_source(self):
method test_nat_outbound_update_destination (line 280) | def test_nat_outbound_update_destination(self):
method test_nat_outbound_update_interface (line 286) | def test_nat_outbound_update_interface(self):
method test_nat_outbound_delete (line 292) | def test_nat_outbound_delete(self):
method test_nat_outbound_invalid_sourcehashkey_hex (line 298) | def test_nat_outbound_invalid_sourcehashkey_hex(self):
method test_nat_outbound_invalid_sourcehashkey_len (line 304) | def test_nat_outbound_invalid_sourcehashkey_len(self):
FILE: tests/unit/plugins/modules/test_pfsense_nat_port_forward.py
class TestPFSenseNatPortForwardModule (line 19) | class TestPFSenseNatPortForwardModule(TestPFSenseModule):
method __init__ (line 23) | def __init__(self, *args, **kwargs):
method check_target_addr (line 28) | def check_target_addr(self, params, target_elt):
method get_associated_rule_elt (line 34) | def get_associated_rule_elt(self, params, ruleid):
method check_target_elt (line 41) | def check_target_elt(self, obj, target_elt, target_idx=-1):
method check_rule_idx (line 74) | def check_rule_idx(self, params, target_idx):
method get_target_elt (line 91) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_nat_port_forward_create (line 105) | def test_nat_port_forward_create(self):
method test_nat_port_forward_create_range (line 113) | def test_nat_port_forward_create_range(self):
method test_nat_port_forward_create_associated (line 122) | def test_nat_port_forward_create_associated(self):
method test_nat_port_forward_create_unassociated (line 129) | def test_nat_port_forward_create_unassociated(self):
method test_nat_port_forward_create_top (line 139) | def test_nat_port_forward_create_top(self):
method test_nat_port_forward_create_after (line 148) | def test_nat_port_forward_create_after(self):
method test_nat_port_forward_create_before (line 157) | def test_nat_port_forward_create_before(self):
method test_nat_port_forward_create_icmp (line 166) | def test_nat_port_forward_create_icmp(self):
method test_nat_port_forward_create_tcp_fail_no_port (line 175) | def test_nat_port_forward_create_tcp_fail_no_port(self):
method test_nat_port_forward_create_icmp_fail_port (line 181) | def test_nat_port_forward_create_icmp_fail_port(self):
method test_nat_port_forward_update_noop (line 187) | def test_nat_port_forward_update_noop(self):
method test_nat_port_forward_update_bottom (line 192) | def test_nat_port_forward_update_bottom(self):
method test_nat_port_forward_update_top (line 198) | def test_nat_port_forward_update_top(self):
method test_nat_port_forward_update_source (line 204) | def test_nat_port_forward_update_source(self):
method test_nat_port_forward_update_destination (line 210) | def test_nat_port_forward_update_destination(self):
method test_nat_port_forward_update_interface (line 216) | def test_nat_port_forward_update_interface(self):
method test_nat_port_forward_update_interface_associated (line 222) | def test_nat_port_forward_update_interface_associated(self):
method test_nat_port_forward_delete (line 230) | def test_nat_port_forward_delete(self):
FILE: tests/unit/plugins/modules/test_pfsense_openvpn_override.py
class TestPFSenseOpenVPNOverrideModule (line 17) | class TestPFSenseOpenVPNOverrideModule(TestPFSenseModule):
method __init__ (line 21) | def __init__(self, *args, **kwargs):
method runTest (line 27) | def runTest():
method get_target_elt (line 31) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 42) | def check_target_elt(self, obj, target_elt):
method test_openvpn_override_create (line 60) | def test_openvpn_override_create(self):
method test_openvpn_override_delete (line 65) | def test_openvpn_override_delete(self):
method test_openvpn_override_update_noop (line 70) | def test_openvpn_override_update_noop(self):
method test_openvpn_override_update_network (line 75) | def test_openvpn_override_update_network(self):
method test_create_openvpn_override_invalid_network (line 83) | def test_create_openvpn_override_invalid_network(self):
method test_delete_nonexistent_openvpn_override (line 88) | def test_delete_nonexistent_openvpn_override(self):
FILE: tests/unit/plugins/modules/test_pfsense_openvpn_server.py
class TestPFSenseOpenVPNServerModule (line 43) | class TestPFSenseOpenVPNServerModule(TestPFSenseModule):
method __init__ (line 47) | def __init__(self, *args, **kwargs):
method setUp (line 52) | def setUp(self):
method tearDown (line 65) | def tearDown(self):
method runTest (line 72) | def runTest():
method get_target_elt (line 76) | def get_target_elt(self, obj, absent=False, module_result=None):
method caref (line 88) | def caref(descr):
method crlref (line 95) | def crlref(descr):
method certref (line 102) | def certref(descr):
method check_target_elt (line 108) | def check_target_elt(self, obj, target_elt):
method test_openvpn_server_create (line 167) | def test_openvpn_server_create(self):
method test_openvpn_server_create_generate (line 172) | def test_openvpn_server_create_generate(self):
method test_openvpn_server_delete (line 177) | def test_openvpn_server_delete(self):
method test_openvpn_server_update_noop (line 182) | def test_openvpn_server_update_noop(self):
method test_openvpn_server_update_network (line 187) | def test_openvpn_server_update_network(self):
method test_create_openvpn_server_duplicate_port (line 195) | def test_create_openvpn_server_duplicate_port(self):
method test_create_openvpn_server_invalid_certificate (line 200) | def test_create_openvpn_server_invalid_certificate(self):
method test_delete_nonexistent_openvpn_server (line 205) | def test_delete_nonexistent_openvpn_server(self):
FILE: tests/unit/plugins/modules/test_pfsense_route.py
class TestPFSenseRouteModule (line 19) | class TestPFSenseRouteModule(TestPFSenseModule):
method __init__ (line 23) | def __init__(self, *args, **kwargs):
method setUp (line 28) | def setUp(self):
method tearDown (line 37) | def tearDown(self):
method check_target_elt (line 43) | def check_target_elt(self, obj, target_elt):
method get_target_elt (line 50) | def get_target_elt(self, obj, absent=False, module_result=None):
method test_route_create (line 64) | def test_route_create(self):
method test_route_create_invalid_gw (line 70) | def test_route_create_invalid_gw(self):
method test_route_create_invalid_ip (line 76) | def test_route_create_invalid_ip(self):
method test_route_create_invalid_ip2 (line 82) | def test_route_create_invalid_ip2(self):
method test_route_create_invalid_alias (line 88) | def test_route_create_invalid_alias(self):
method test_route_update_noop (line 94) | def test_route_update_noop(self):
method test_route_update_network (line 99) | def test_route_update_network(self):
method test_route_update_gateway (line 105) | def test_route_update_gateway(self):
method test_route_delete (line 111) | def test_route_delete(self):
method test_route_delete_alias (line 117) | def test_route_delete_alias(self):
method test_route_create_dhcp (line 123) | def test_route_create_dhcp(self):
method test_route_create_dhcp6 (line 129) | def test_route_create_dhcp6(self):
FILE: tests/unit/plugins/modules/test_pfsense_rule.py
class TestPFSenseRuleModule (line 19) | class TestPFSenseRuleModule(TestPFSenseModule):
method __init__ (line 23) | def __init__(self, *args, **kwargs):
method runTest (line 29) | def runTest():
method parse_address (line 33) | def parse_address(self, addr):
method check_rule_elt_addr (line 63) | def check_rule_elt_addr(self, rule, rule_elt, addr):
method get_target_elt (line 82) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 89) | def check_target_elt(self, obj, target_elt):
method check_rule_idx (line 185) | def check_rule_idx(self, rule, target_idx):
method check_separator_idx (line 209) | def check_separator_idx(self, interface, sep_name, expected_idx):
FILE: tests/unit/plugins/modules/test_pfsense_rule_create.py
class TestPFSenseRuleCreateModule (line 16) | class TestPFSenseRuleCreateModule(TestPFSenseRuleModule):
method test_rule_create_one_rule (line 21) | def test_rule_create_one_rule(self):
method test_rule_create_log (line 27) | def test_rule_create_log(self):
method test_rule_create_nolog (line 33) | def test_rule_create_nolog(self):
method test_rule_create_pass (line 39) | def test_rule_create_pass(self):
method test_rule_create_block (line 45) | def test_rule_create_block(self):
method test_rule_create_reject (line 51) | def test_rule_create_reject(self):
method test_rule_create_disabled (line 57) | def test_rule_create_disabled(self):
method test_rule_create_floating (line 63) | def test_rule_create_floating(self):
method test_rule_create_floating_any (line 69) | def test_rule_create_floating_any(self):
method test_rule_create_non_floating_any (line 74) | def test_rule_create_non_floating_any(self):
method test_rule_create_floating_quick (line 80) | def test_rule_create_floating_quick(self):
method test_rule_create_nofloating (line 86) | def test_rule_create_nofloating(self):
method test_rule_create_floating_interfaces (line 92) | def test_rule_create_floating_interfaces(self):
method test_rule_create_inet46 (line 98) | def test_rule_create_inet46(self):
method test_rule_create_inet6 (line 104) | def test_rule_create_inet6(self):
method test_rule_create_tcp (line 110) | def test_rule_create_tcp(self):
method test_rule_create_udp (line 116) | def test_rule_create_udp(self):
method test_rule_create_tcp_udp (line 122) | def test_rule_create_tcp_udp(self):
method test_rule_create_icmp (line 128) | def test_rule_create_icmp(self):
method test_rule_create_icmp_redir (line 134) | def test_rule_create_icmp_redir(self):
method test_rule_create_icmp_invalid_inet (line 140) | def test_rule_create_icmp_invalid_inet(self):
method test_rule_create_icmp_invalid_inet6 (line 146) | def test_rule_create_icmp_invalid_inet6(self):
method test_rule_create_icmp_invalid_inet46 (line 152) | def test_rule_create_icmp_invalid_inet46(self):
method test_rule_create_icmp_invalid_empty (line 158) | def test_rule_create_icmp_invalid_empty(self):
method test_rule_create_esp (line 164) | def test_rule_create_esp(self):
method test_rule_create_protocol_any (line 170) | def test_rule_create_protocol_any(self):
method test_rule_create_tcpflags_any (line 176) | def test_rule_create_tcpflags_any(self):
method test_rule_create_state_keep (line 182) | def test_rule_create_state_keep(self):
method test_rule_create_state_sloppy (line 188) | def test_rule_create_state_sloppy(self):
method test_rule_create_state_synproxy (line 194) | def test_rule_create_state_synproxy(self):
method test_rule_create_state_none (line 201) | def test_rule_create_state_none(self):
method test_rule_create_state_invalid (line 207) | def test_rule_create_state_invalid(self):
method test_rule_create_after (line 213) | def test_rule_create_after(self):
method test_rule_create_after_top (line 220) | def test_rule_create_after_top(self):
method test_rule_create_after_invalid (line 227) | def test_rule_create_after_invalid(self):
method test_rule_create_before (line 233) | def test_rule_create_before(self):
method test_rule_create_before_bottom (line 240) | def test_rule_create_before_bottom(self):
method test_rule_create_before_bottom_default (line 247) | def test_rule_create_before_bottom_default(self):
method test_rule_create_before_invalid (line 254) | def test_rule_create_before_invalid(self):
method test_rule_create_source_alias (line 260) | def test_rule_create_source_alias(self):
method test_rule_create_source_urltable_alias (line 266) | def test_rule_create_source_urltable_alias(self):
method test_rule_create_source_alias_invalid (line 272) | def test_rule_create_source_alias_invalid(self):
method test_rule_create_invalid_ports (line 278) | def test_rule_create_invalid_ports(self):
method test_rule_create_source_ip_invalid (line 284) | def test_rule_create_source_ip_invalid(self):
method test_rule_create_source_net_invalid (line 290) | def test_rule_create_source_net_invalid(self):
method test_rule_create_destination_alias (line 296) | def test_rule_create_destination_alias(self):
method test_rule_create_destination_alias_invalid (line 302) | def test_rule_create_destination_alias_invalid(self):
method test_rule_create_destination_ip_invalid (line 308) | def test_rule_create_destination_ip_invalid(self):
method test_rule_create_destination_net_invalid (line 314) | def test_rule_create_destination_net_invalid(self):
method test_rule_create_source_self_lan (line 320) | def test_rule_create_source_self_lan(self):
method test_rule_create_ip_to_ip (line 326) | def test_rule_create_ip_to_ip(self):
method test_rule_create_ip6_to_ip6 (line 332) | def test_rule_create_ip6_to_ip6(self):
method test_rule_create_net_to_net (line 338) | def test_rule_create_net_to_net(self):
method test_rule_create_net6_to_net6 (line 344) | def test_rule_create_net6_to_net6(self):
method test_rule_create_net_interface (line 350) | def test_rule_create_net_interface(self):
method test_rule_create_net_interface_invalid (line 356) | def test_rule_create_net_interface_invalid(self):
method test_rule_create_net_interface_invalid2 (line 362) | def test_rule_create_net_interface_invalid2(self):
method test_rule_create_ip_interface (line 368) | def test_rule_create_ip_interface(self):
method test_rule_create_ip_interface_with_port (line 374) | def test_rule_create_ip_interface_with_port(self):
method test_rule_create_ip_interface_invalid (line 380) | def test_rule_create_ip_interface_invalid(self):
method test_rule_create_interface (line 386) | def test_rule_create_interface(self):
method test_rule_create_port_number (line 392) | def test_rule_create_port_number(self):
method test_rule_create_port_alias (line 398) | def test_rule_create_port_alias(self):
method test_rule_create_urltable_port_alias (line 404) | def test_rule_create_urltable_port_alias(self):
method test_rule_create_port_range (line 410) | def test_rule_create_port_range(self):
method test_rule_create_port_alias_range (line 416) | def test_rule_create_port_alias_range(self):
method test_rule_create_port_alias_range_invalid_1 (line 422) | def test_rule_create_port_alias_range_invalid_1(self):
method test_rule_create_port_alias_range_invalid_2 (line 428) | def test_rule_create_port_alias_range_invalid_2(self):
method test_rule_create_port_alias_range_invalid_3 (line 434) | def test_rule_create_port_alias_range_invalid_3(self):
method test_rule_create_port_number_invalid (line 440) | def test_rule_create_port_number_invalid(self):
method test_rule_create_port_alias_invalid (line 446) | def test_rule_create_port_alias_invalid(self):
method test_rule_create_negate_source (line 452) | def test_rule_create_negate_source(self):
method test_rule_create_negate_destination (line 458) | def test_rule_create_negate_destination(self):
method test_rule_create_separator_top (line 464) | def test_rule_create_separator_top(self):
method test_rule_create_separator_bottom (line 473) | def test_rule_create_separator_bottom(self):
method test_rule_create_separator_before_first (line 482) | def test_rule_create_separator_before_first(self):
method test_rule_create_separator_after_third (line 491) | def test_rule_create_separator_after_third(self):
method test_rule_create_queue (line 500) | def test_rule_create_queue(self):
method test_rule_create_queue_ack (line 506) | def test_rule_create_queue_ack(self):
method test_rule_create_queue_ack_without_default (line 512) | def test_rule_create_queue_ack_without_default(self):
method test_rule_create_queue_same (line 518) | def test_rule_create_queue_same(self):
method test_rule_create_queue_invalid (line 524) | def test_rule_create_queue_invalid(self):
method test_rule_create_queue_invalid_ack (line 530) | def test_rule_create_queue_invalid_ack(self):
method test_rule_create_limiter (line 536) | def test_rule_create_limiter(self):
method test_rule_create_limiter_out (line 542) | def test_rule_create_limiter_out(self):
method test_rule_create_limiter_disabled (line 548) | def test_rule_create_limiter_disabled(self):
method test_rule_create_limiter_out_without_in (line 554) | def test_rule_create_limiter_out_without_in(self):
method test_rule_create_limiter_same (line 560) | def test_rule_create_limiter_same(self):
method test_rule_create_limiter_invalid (line 566) | def test_rule_create_limiter_invalid(self):
method test_rule_create_limiter_invalid_out (line 572) | def test_rule_create_limiter_invalid_out(self):
method test_rule_create_limiter_floating_any (line 578) | def test_rule_create_limiter_floating_any(self):
method test_rule_create_gateway (line 584) | def test_rule_create_gateway(self):
method test_rule_create_gateway_invalid (line 590) | def test_rule_create_gateway_invalid(self):
method test_rule_create_gateway_invalid_ipprotocol (line 596) | def test_rule_create_gateway_invalid_ipprotocol(self):
method test_rule_create_gateway_floating (line 602) | def test_rule_create_gateway_floating(self):
method test_rule_create_gateway_floating_any (line 608) | def test_rule_create_gateway_floating_any(self):
method test_rule_create_gateway_group (line 614) | def test_rule_create_gateway_group(self):
method test_rule_create_gateway_group_invalid_ipprotocol (line 620) | def test_rule_create_gateway_group_invalid_ipprotocol(self):
method test_rule_create_tracker (line 626) | def test_rule_create_tracker(self):
method test_rule_create_tracker_leading0 (line 632) | def test_rule_create_tracker_leading0(self):
method test_rule_create_tracker_invalid (line 638) | def test_rule_create_tracker_invalid(self):
method test_rule_create_schedule (line 644) | def test_rule_create_schedule(self):
method test_rule_create_schedule_invalid (line 650) | def test_rule_create_schedule_invalid(self):
method test_rule_create_protocol_any_with_dst_port (line 659) | def test_rule_create_protocol_any_with_dst_port(self):
method test_rule_create_protocol_icmp_with_dst_port (line 665) | def test_rule_create_protocol_icmp_with_dst_port(self):
method test_rule_create_pass_before_block (line 674) | def test_rule_create_pass_before_block(self):
method test_rule_create_block_appends_to_end (line 694) | def test_rule_create_block_appends_to_end(self):
method test_rule_create_pass_before_reject (line 714) | def test_rule_create_pass_before_reject(self):
FILE: tests/unit/plugins/modules/test_pfsense_rule_misc.py
class TestPFSenseRuleMiscModule (line 17) | class TestPFSenseRuleMiscModule(TestPFSenseRuleModule):
method test_rule_delete (line 22) | def test_rule_delete(self):
method test_check_mode (line 31) | def test_check_mode(self):
FILE: tests/unit/plugins/modules/test_pfsense_rule_noop.py
class TestPFSenseRuleNoopModule (line 16) | class TestPFSenseRuleNoopModule(TestPFSenseRuleModule):
method test_rule_noop_action (line 21) | def test_rule_noop_action(self):
method test_rule_noop_disabled (line 26) | def test_rule_noop_disabled(self):
method test_rule_noop_enabled (line 31) | def test_rule_noop_enabled(self):
method test_rule_noop_disabled_default (line 36) | def test_rule_noop_disabled_default(self):
method test_rule_noop_floating_interface (line 41) | def test_rule_noop_floating_interface(self):
method test_rule_noop_floating_direction (line 46) | def test_rule_noop_floating_direction(self):
method test_rule_noop_inet (line 51) | def test_rule_noop_inet(self):
method test_rule_noop_protocol (line 56) | def test_rule_noop_protocol(self):
method test_rule_noop_log_no (line 61) | def test_rule_noop_log_no(self):
method test_rule_noop_log_yes (line 66) | def test_rule_noop_log_yes(self):
method test_rule_noop_log_default (line 71) | def test_rule_noop_log_default(self):
method test_rule_noop_source_and_destination (line 76) | def test_rule_noop_source_and_destination(self):
method test_rule_noop_negate_source (line 81) | def test_rule_noop_negate_source(self):
method test_rule_noop_negate_destination (line 86) | def test_rule_noop_negate_destination(self):
method test_rule_noop_before (line 91) | def test_rule_noop_before(self):
method test_rule_noop_before_bottom (line 96) | def test_rule_noop_before_bottom(self):
method test_rule_noop_position_bottom (line 101) | def test_rule_noop_position_bottom(self):
method test_rule_noop_position_middle (line 106) | def test_rule_noop_position_middle(self):
method test_rule_noop_after (line 111) | def test_rule_noop_after(self):
method test_rule_noop_after_top (line 116) | def test_rule_noop_after_top(self):
method test_rule_noop_separator_top (line 121) | def test_rule_noop_separator_top(self):
method test_rule_noop_separator_bottom (line 126) | def test_rule_noop_separator_bottom(self):
method test_rule_noop_queue_ack (line 131) | def test_rule_noop_queue_ack(self):
method test_rule_noop_queue (line 136) | def test_rule_noop_queue(self):
method test_rule_noop_limiter_out (line 141) | def test_rule_noop_limiter_out(self):
method test_rule_noop_limiter_in (line 147) | def test_rule_noop_limiter_in(self):
method test_rule_noop_tracker (line 152) | def test_rule_noop_tracker(self):
method test_rule_noop_tracker (line 157) | def test_rule_noop_tracker(self):
method test_rule_noop_schedule (line 162) | def test_rule_noop_schedule(self):
FILE: tests/unit/plugins/modules/test_pfsense_rule_separator.py
class TestPFSenseRuleSeparatorModule (line 17) | class TestPFSenseRuleSeparatorModule(TestPFSenseModule):
method __init__ (line 21) | def __init__(self, *args, **kwargs):
method get_target_elt (line 26) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 47) | def check_target_elt(self, obj, target_elt):
method check_separator_idx (line 61) | def check_separator_idx(self, separator, expected_idx):
method test_separator_create (line 72) | def test_separator_create(self):
method test_separator_create_floating (line 79) | def test_separator_create_floating(self):
method test_separator_create_top (line 86) | def test_separator_create_top(self):
method test_separator_create_bottom (line 93) | def test_separator_create_bottom(self):
method test_separator_create_after (line 100) | def test_separator_create_after(self):
method test_separator_create_before (line 107) | def test_separator_create_before(self):
method test_separator_delete (line 114) | def test_separator_delete(self):
method test_separator_delete_inexistent (line 120) | def test_separator_delete_inexistent(self):
method test_separator_update_noop (line 125) | def test_separator_update_noop(self):
method test_separator_update_color (line 130) | def test_separator_update_color(self):
method test_separator_update_position (line 137) | def test_separator_update_position(self):
FILE: tests/unit/plugins/modules/test_pfsense_rule_update.py
class TestPFSenseRuleUpdateModule (line 16) | class TestPFSenseRuleUpdateModule(TestPFSenseRuleModule):
method test_rule_update_action (line 21) | def test_rule_update_action(self):
method test_rule_update_disabled (line 27) | def test_rule_update_disabled(self):
method test_rule_update_enabled (line 33) | def test_rule_update_enabled(self):
method test_rule_update_enabled_default (line 39) | def test_rule_update_enabled_default(self):
method test_rule_update_floating_interface (line 45) | def test_rule_update_floating_interface(self):
method test_rule_update_floating_interfaces (line 51) | def test_rule_update_floating_interfaces(self):
method test_rule_update_floating_direction (line 57) | def test_rule_update_floating_direction(self):
method test_rule_update_floating_quick (line 63) | def test_rule_update_floating_quick(self):
method test_rule_update_floating_remove_quick (line 69) | def test_rule_update_floating_remove_quick(self):
method test_rule_update_floating_yes (line 75) | def test_rule_update_floating_yes(self):
method test_rule_update_floating_no (line 87) | def test_rule_update_floating_no(self):
method test_rule_update_floating_default (line 99) | def test_rule_update_floating_default(self):
method test_rule_update_inet (line 111) | def test_rule_update_inet(self):
method test_rule_update_protocol_udp (line 117) | def test_rule_update_protocol_udp(self):
method test_rule_update_protocol_any (line 123) | def test_rule_update_protocol_any(self):
method test_rule_update_protocol_tcp_udp (line 129) | def test_rule_update_protocol_tcp_udp(self):
method test_rule_update_log_yes (line 135) | def test_rule_update_log_yes(self):
method test_rule_update_log_no (line 141) | def test_rule_update_log_no(self):
method test_rule_update_tcpflags_any_yes (line 147) | def test_rule_update_tcpflags_any_yes(self):
method test_rule_update_tcpflags_any_no (line 153) | def test_rule_update_tcpflags_any_no(self):
method test_rule_update_log_default (line 159) | def test_rule_update_log_default(self):
method test_rule_update_negate_add_source (line 165) | def test_rule_update_negate_add_source(self):
method test_rule_update_negate_add_destination (line 171) | def test_rule_update_negate_add_destination(self):
method test_rule_update_negate_remove_source (line 177) | def test_rule_update_negate_remove_source(self):
method test_rule_update_negate_remove_destination (line 183) | def test_rule_update_negate_remove_destination(self):
method test_rule_update_before (line 189) | def test_rule_update_before(self):
method test_rule_update_before_bottom (line 196) | def test_rule_update_before_bottom(self):
method test_rule_update_after (line 203) | def test_rule_update_after(self):
method test_rule_update_after_self (line 210) | def test_rule_update_after_self(self):
method test_rule_update_before_self (line 216) | def test_rule_update_before_self(self):
method test_rule_update_after_top (line 222) | def test_rule_update_after_top(self):
method test_rule_update_separator_top (line 229) | def test_rule_update_separator_top(self):
method test_rule_update_separator_bottom (line 238) | def test_rule_update_separator_bottom(self):
method test_rule_update_separator_before_first (line 247) | def test_rule_update_separator_before_first(self):
method test_rule_update_separator_after_third (line 256) | def test_rule_update_separator_after_third(self):
method test_rule_update_queue_set (line 265) | def test_rule_update_queue_set(self):
method test_rule_update_queue_set_ack (line 271) | def test_rule_update_queue_set_ack(self):
method test_rule_update_queue_unset_ack (line 277) | def test_rule_update_queue_unset_ack(self):
method test_rule_update_queue_unset (line 283) | def test_rule_update_queue_unset(self):
method test_rule_update_limiter_set (line 289) | def test_rule_update_limiter_set(self):
method test_rule_update_limiter_set_out (line 295) | def test_rule_update_limiter_set_out(self):
method test_rule_update_limiter_unset_out (line 301) | def test_rule_update_limiter_unset_out(self):
method test_rule_update_limiter_unset (line 307) | def test_rule_update_limiter_unset(self):
method test_rule_update_gateway_set (line 313) | def test_rule_update_gateway_set(self):
method test_rule_update_gateway_unset (line 319) | def test_rule_update_gateway_unset(self):
method test_rule_update_tracker (line 325) | def test_rule_update_tracker(self):
method test_rule_update_icmp (line 331) | def test_rule_update_icmp(self):
method test_rule_update_port_old_syntax (line 337) | def test_rule_update_port_old_syntax(self):
method test_rule_update_port_new_syntax (line 343) | def test_rule_update_port_new_syntax(self):
method test_rule_update_schedule (line 349) | def test_rule_update_schedule(self):
method test_rule_update_remove_schedule (line 355) | def test_rule_update_remove_schedule(self):
FILE: tests/unit/plugins/modules/test_pfsense_setup.py
class TestPFSenseSetupModule (line 18) | class TestPFSenseSetupModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_args_fields (line 27) | def get_args_fields():
method setUp (line 35) | def setUp(self):
method tearDown (line 49) | def tearDown(self):
method get_target_elt (line 59) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 63) | def check_target_elt(self, obj, target_elt):
method test_setup_hostname (line 109) | def test_setup_hostname(self):
method test_setup_hostname_invalid (line 115) | def test_setup_hostname_invalid(self):
method test_setup_hostname_invalid2 (line 121) | def test_setup_hostname_invalid2(self):
method test_setup_domain (line 127) | def test_setup_domain(self):
method test_setup_domain_invalid (line 133) | def test_setup_domain_invalid(self):
method test_setup_dnsallowoverride (line 139) | def test_setup_dnsallowoverride(self):
method test_setup_dnslocalhost (line 145) | def test_setup_dnslocalhost(self):
method test_setup_webguifixedmenu (line 151) | def test_setup_webguifixedmenu(self):
method test_setup_interfacessort (line 157) | def test_setup_interfacessort(self):
method test_setup_dashboardavailablewidgetspanel (line 163) | def test_setup_dashboardavailablewidgetspanel(self):
method test_setup_systemlogsfilterpanel (line 169) | def test_setup_systemlogsfilterpanel(self):
method test_setup_systemlogsmanagelogpanel (line 175) | def test_setup_systemlogsmanagelogpanel(self):
method test_setup_statusmonitoringsettingspanel (line 181) | def test_setup_statusmonitoringsettingspanel(self):
method test_setup_requirestatefilter (line 187) | def test_setup_requirestatefilter(self):
method test_setup_webguileftcolumnhyper (line 193) | def test_setup_webguileftcolumnhyper(self):
method test_setup_disablealiaspopupdetail (line 199) | def test_setup_disablealiaspopupdetail(self):
method test_setup_roworderdragging (line 205) | def test_setup_roworderdragging(self):
method test_setup_loginshowhost (line 211) | def test_setup_loginshowhost(self):
method test_setup_language (line 217) | def test_setup_language(self):
method test_setup_timeservers (line 223) | def test_setup_timeservers(self):
method test_setup_timezone (line 229) | def test_setup_timezone(self):
method test_setup_webguicss (line 235) | def test_setup_webguicss(self):
method test_setup_webguihostnamemenu (line 241) | def test_setup_webguihostnamemenu(self):
method test_setup_dashboardcolumns (line 247) | def test_setup_dashboardcolumns(self):
method test_setup_dashboardcolumns_invalid (line 253) | def test_setup_dashboardcolumns_invalid(self):
method test_setup_logincss (line 259) | def test_setup_logincss(self):
method test_setup_logincss_invalid (line 265) | def test_setup_logincss_invalid(self):
method test_setup_dns_addresses (line 271) | def test_setup_dns_addresses(self):
method test_setup_dns_addresses_invalid (line 277) | def test_setup_dns_addresses_invalid(self):
method test_setup_dns_addresses_ipv6 (line 283) | def test_setup_dns_addresses_ipv6(self):
method test_setup_dns_addresses_invalid_ipv4 (line 289) | def test_setup_dns_addresses_invalid_ipv4(self):
method test_setup_dns_addresses_invalid_ipv6 (line 295) | def test_setup_dns_addresses_invalid_ipv6(self):
method test_setup_dns_addresses_invalid_gw (line 301) | def test_setup_dns_addresses_invalid_gw(self):
method test_setup_dns_addresses_invalid_gw2 (line 307) | def test_setup_dns_addresses_invalid_gw2(self):
method test_setup_dns_addresses_duplicates (line 313) | def test_setup_dns_addresses_duplicates(self):
FILE: tests/unit/plugins/modules/test_pfsense_user.py
class TestPFSenseUserModule (line 17) | class TestPFSenseUserModule(TestPFSenseModule):
method __init__ (line 21) | def __init__(self, *args, **kwargs):
method runTest (line 27) | def runTest():
method get_target_elt (line 31) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 42) | def check_target_elt(self, obj, target_elt):
method test_user_create (line 58) | def test_user_create(self):
method test_user_delete (line 63) | def test_user_delete(self):
method test_user_update_noop (line 68) | def test_user_update_noop(self):
method test_user_update_descr (line 73) | def test_user_update_descr(self):
method test_create_user_invalid_password (line 82) | def test_create_user_invalid_password(self):
method test_delete_inexistent_user (line 87) | def test_delete_inexistent_user(self):
FILE: tests/unit/plugins/modules/test_pfsense_vlan.py
class TestPFSenseVlanModule (line 18) | class TestPFSenseVlanModule(TestPFSenseModule):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method get_target_elt (line 31) | def get_target_elt(self, obj, absent=False, module_result=None):
method check_target_elt (line 39) | def check_target_elt(self, obj, target_elt):
method test_vlan_create (line 60) | def test_vlan_create(self):
method test_vlan_create_with_assigned_name (line 66) | def test_vlan_create_with_assigned_name(self):
method test_vlan_create_with_friendly_name (line 72) | def test_vlan_create_with_friendly_name(self):
method test_vlan_create_with_wrong_inteface (line 78) | def test_vlan_create_with_wrong_inteface(self):
method test_vlan_create_with_wrong_vlan (line 84) | def test_vlan_create_with_wrong_vlan(self):
method test_vlan_create_with_wrong_prioriy (line 90) | def test_vlan_create_with_wrong_prioriy(self):
method test_vlan_create_with_priority (line 96) | def test_vlan_create_with_priority(self):
method test_vlan_create_with_descr (line 102) | def test_vlan_create_with_descr(self):
method test_vlan_delete (line 108) | def test_vlan_delete(self):
method test_vlan_delete_used (line 114) | def test_vlan_delete_used(self):
method test_vlan_delete_unexistent (line 119) | def test_vlan_delete_unexistent(self):
method test_vlan_update_noop (line 124) | def test_vlan_update_noop(self):
method test_vlan_update_priority (line 129) | def test_vlan_update_priority(self):
method test_vlan_update_descr (line 135) | def test_vlan_update_descr(self):
Condensed preview — 211 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,161K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 944,
"preview": "# These are supported funding model platforms\n\ngithub: opoplawski # Replace with up to 4 GitHub Sponsors-enabled usernam"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 587,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the "
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 595,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
},
{
"path": ".github/workflows/main.yml",
"chars": 2347,
"preview": "name: CI\n\n# Controls when the workflow will run\non:\n # Triggers the workflow on push or pull request events\n push:\n p"
},
{
"path": ".gitignore",
"chars": 1279,
"preview": "# test output\ntests/output/\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*"
},
{
"path": "CHANGELOG.rst",
"chars": 8959,
"preview": "=============================\npfSensible.Core Release Notes\n=============================\n\n.. contents:: Topics\n\nv0.7.1\n"
},
{
"path": "GENERATING_MODULES.md",
"chars": 2369,
"preview": "# Generating Modules with pfsensible-generate-module\n\nThe process of writing basic pfsensible modules is hopefully great"
},
{
"path": "LICENSE",
"chars": 35147,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README.md",
"chars": 6889,
"preview": "# ansible-pfsense / pfsensible.core\n\nThis is a set of modules to allow you to configure pfSense firewalls with ansible.\n"
},
{
"path": "changelogs/.plugin-cache.yaml",
"chars": 5882,
"preview": "objects: {}\nplugins:\n become: {}\n cache: {}\n callback: {}\n cliconf: {}\n connection: {}\n httpapi: {}\n inventory: {"
},
{
"path": "changelogs/134_openvpn_digest.yml",
"chars": 132,
"preview": "bugfixes:\n - pfsense_openvpn_client/server - Support additional digest values\n (https://github.com/pfsensible/core/i"
},
{
"path": "changelogs/changelog.yaml",
"chars": 11294,
"preview": "ancestor: null\nreleases:\n 0.6.0:\n changes:\n bugfixes:\n - pfsense_aggregate - Fix where a rule with a dupli"
},
{
"path": "changelogs/config.yaml",
"chars": 803,
"preview": "changelog_filename_template: ../CHANGELOG.rst\nchangelog_filename_version_depth: 0\nchanges_file: changelog.yaml\nchanges_f"
},
{
"path": "changelogs/fragments/129_sshguard_whitelist.yaml",
"chars": 116,
"preview": "minor_changes:\n - pfsense_setup - added sshguard_whitelist option (https://github.com/pfsensible/core/issues/129).\n"
},
{
"path": "changelogs/fragments/217_pfsense_setup_webguicert.yml",
"chars": 111,
"preview": "minor_changes:\n - pfsense_setup - add ``webguicert`` parameter (https://github.com/pfsensible/core/pull/217).\n"
},
{
"path": "changelogs/fragments/219_parse_address_ipv6.yml",
"chars": 125,
"preview": "bugfixes:\n - pfsense_rule - Allow IPv6 addresses in source and destination (https://github.com/pfsensible/core/issues/2"
},
{
"path": "changelogs/fragments/223_fix_openvpn_alias_expansion.yml",
"chars": 151,
"preview": "minor_changes:\n - pfsense_openvpn_server - add call to ``alias_make_table()`` to allow alias expansion (https://github."
},
{
"path": "changelogs/fragments/224_add_dco_for_plus_versions.yml",
"chars": 188,
"preview": "minor_changes:\n - pfsense_openvpn_server - add ``dco`` parameter (https://github.com/pfsensible/core/pull/224).\n - imp"
},
{
"path": "changelogs/fragments/226_dns_resolver.yaml",
"chars": 135,
"preview": "bugfixes:\n - pfsense_dns_resolver - Allow IPv6 addresses for hosts and domainoverrides (https://github.com/pfsensible/c"
},
{
"path": "changelogs/fragments/228_interface_diff.yml",
"chars": 105,
"preview": "minor_changes:\n - pfsense_interface - support ``--diff`` (https://github.com/pfsensible/core/pull/228).\n"
},
{
"path": "changelogs/fragments/238_pfsense_openvpn_server.yml",
"chars": 442,
"preview": "bugfixes:\n - pfsense_openvpn_server - Normalize `tls` text to CRLF line endings to match web interface (https://github."
},
{
"path": "changelogs/fragments/239_sync_config.yml",
"chars": 296,
"preview": "bugfixes:\n - pfsense_rewrite_config - Drop obsolete and unneeded call to parse_config() (https://github.com/pfsensible/"
},
{
"path": "changelogs/fragments/242_gateway_loss.yml",
"chars": 116,
"preview": "minor_changes:\n - pfsense_gateway - Add losshigh/losslow parameters (https://github.com/pfsensible/core/pull/242).\n"
},
{
"path": "changelogs/fragments/243_openvpn_client.yml",
"chars": 275,
"preview": "bugfixes:\n - pfsense_openvpn_client - Fix index calculation so that it actually updates the running client configuration"
},
{
"path": "changelogs/fragments/245_arg_route.yaml",
"chars": 93,
"preview": "bugfixes:\n - Fix initialization of arg_route (https://github.com/pfsensible/core/pull/245).\n"
},
{
"path": "changelogs/fragments/248_class_level_imports.yaml",
"chars": 140,
"preview": "minor_changes:\n - Remove class level imports in PFSenseModule to support the use of Mitogen (https://github.com/pfsensi"
},
{
"path": "changelogs/fragments/251_setup_hardware.yaml",
"chars": 134,
"preview": "minor_changes:\n - pfsense_setup - add crypto_hardware and thermal_hardware parameters (https://github.com/pfsensible/co"
},
{
"path": "changelogs/fragments/rule_pass_before_deny_ordering.yml",
"chars": 213,
"preview": "bugfixes:\n - pfsense_rule - New pass/match rules without explicit ``after`` or ``before`` are now inserted before the f"
},
{
"path": "changelogs/fragments/rule_protocol_any_with_ports.yml",
"chars": 114,
"preview": "bugfixes:\n - pfsense_rule - Allow protocol ``any`` with destination/source ports, matching pfSense UI behaviour.\n"
},
{
"path": "examples/ipsec/README.md",
"chars": 1691,
"preview": "# Managing ipsec tunnels with ansible-pfsense\n\nThis example will demonstrate how to manage your ipsec configuration.\n\nIt"
},
{
"path": "examples/ipsec/filter_plugins/pfsense.py",
"chars": 6808,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "examples/ipsec/hosts",
"chars": 304,
"preview": "[pfsense]\npf_1 ansible_ssh_host=10.0.1.1 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense\npf_2 ansible"
},
{
"path": "examples/ipsec/ipsecs.yaml",
"chars": 876,
"preview": "ipsec_tunnels:\n fully_connected_vpn:\n iketype: ikev2\n interface: wan\n myid_type: keyid tag\n peerid_type: ke"
},
{
"path": "examples/ipsec/more.ipsecs.yaml",
"chars": 973,
"preview": "ipsec_tunnels:\n fully_connected_vpn:\n iketype: ikev2\n interface: wan\n myid_type: keyid tag\n peerid_type: ke"
},
{
"path": "examples/ipsec/setup_ipsec.yml",
"chars": 572,
"preview": "---\n- hosts: pfsense\n gather_facts: false\n connection: paramiko\n\n vars_files:\n ipsecs.yaml\n\n vars:\n params: \"{"
},
{
"path": "examples/lookup/README.md",
"chars": 7330,
"preview": "# Managing rules with lookup plugin\n\nThis example will demonstrate how to easily manage your rules configuration.\n\nIt is"
},
{
"path": "examples/lookup/hosts",
"chars": 224,
"preview": "[pfsense]\npf_paris ansible_ssh_host=10.20.30.101 ansible_ssh_port=22 ansible_ssh_user=root ansible_password=pfsense\npf_f"
},
{
"path": "examples/lookup/pfsense_definitions.yaml",
"chars": 4152,
"preview": "---\n\n###################################################################################################################"
},
{
"path": "examples/lookup/setup_all_rules.yml",
"chars": 572,
"preview": "---\n- hosts: pfsense\n gather_facts: true\n connection: paramiko\n\n vars:\n params: \"{{ lookup('pfsense', 'examples/lo"
},
{
"path": "examples/pfsense.yml",
"chars": 42,
"preview": "---\n- hosts: pfsense\n roles:\n - pfsense\n"
},
{
"path": "examples/pfsense_setup.yml",
"chars": 142,
"preview": "---\n- hosts: pfsense\n # For initial password connection use paramiko to handle BSD prompts\n connection: paramiko\n rol"
},
{
"path": "examples/roles/pfsense/tasks/fail2ban.yml",
"chars": 869,
"preview": "---\n- block:\n - name: \"Add fail2ban alias\"\n pfsensible.core.pfsense_alias:\n name: fail2ban\n type: urltable"
},
{
"path": "examples/roles/pfsense/tasks/main.yml",
"chars": 1637,
"preview": "---\n- block:\n - name: \"Add aliases\"\n pfsensible.core.pfsense_alias:\n name: \"{{ item.name }}\"\n type: \"{{ it"
},
{
"path": "examples/roles/pfsense_setup/tasks/main.yml",
"chars": 2400,
"preview": "---\n- block:\n - name: \"Load private data\"\n include_vars: keys.yml\n\n # Different releases of pfSense work with diffe"
},
{
"path": "examples/roles/pfsense_setup/tasks/setup_user.yml",
"chars": 887,
"preview": "---\n- block:\n - name: \"Create home directory for {{ user }}\"\n file:\n path: \"/home/{{ user }}\"\n owner: \"{{ "
},
{
"path": "examples/roles/pfsense_setup/templates/nslcd.conf.j2",
"chars": 4877,
"preview": "# This is the configuration file for the LDAP nameservice\n# switch library's nslcd daemon. It configures the mapping\n# b"
},
{
"path": "galaxy.yml",
"chars": 2278,
"preview": "### REQUIRED\n\n# The namespace of the collection. This can be a company/brand/organization or product namespace under whi"
},
{
"path": "meta/runtime.yml",
"chars": 436,
"preview": "plugin_routing:\n modules:\n pfsense_haproxy_backend:\n deprecation:\n removal_version: "
},
{
"path": "misc/.coveragerc",
"chars": 26,
"preview": "[run]\ninclude = *pfsense*\n"
},
{
"path": "misc/ansible2local",
"chars": 614,
"preview": "#!/bin/sh\n\nif [ -z \"${ANSIBLE_HOME}\" ]\nthen\n echo \"ANSIBLE_HOME is undefined. Go into ansible directory and run 'sour"
},
{
"path": "misc/local2ansible",
"chars": 1675,
"preview": "#!/bin/sh\n\nif [ -z \"${ANSIBLE_HOME}\" ]\nthen\n ANSIBLE_INSTALL=`ansible --version 2> /dev/null | grep 'module location'"
},
{
"path": "misc/mkpfcollection",
"chars": 1674,
"preview": "#!/bin/bash -eux\n\nmkdir -p {examples,misc,plugins,tests/unit}\ngit mv library/* plugins/modules/\nrmdir library\ngit mv mod"
},
{
"path": "misc/mkpfsensible",
"chars": 1585,
"preview": "#!/bin/bash -eu\n\n[ ! -d ansible-pfsense ] && echo \"No such directory ansible-pfsense\" && exit 1\n[ ! -d pfsensible/core ]"
},
{
"path": "misc/pfsense_module.py.j2",
"chars": 10043,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) {{ year }}, {{ author_name }} <{{ author_email }}>\n# GNU Gen"
},
{
"path": "misc/pfsensible-generate-module",
"chars": 25931,
"preview": "#!/usr/bin/python3\n\n# Copyright: (c) 2024, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPY"
},
{
"path": "misc/pytest",
"chars": 223,
"preview": "#!/bin/sh\n\nmisc/local2ansible\nif [ ! -f .coveragerc ]; then\n cp -f misc/.coveragerc .\nfi\npython3 -m pytest -v -r a te"
},
{
"path": "misc/run_ansible_sanity_tests",
"chars": 470,
"preview": "#!/bin/sh\n\nif [ -z \"${ANSIBLE_HOME}\" ]\nthen\n echo \"ANSIBLE_HOME is undefined. Go into ansible directory and run 'sour"
},
{
"path": "misc/setup_units_tests",
"chars": 648,
"preview": "#!/bin/sh\n\nif [ -z \"${ANSIBLE_HOME}\" ]\nthen\n echo \"ANSIBLE_HOME is undefined. Go into ansible directory and run 'sour"
},
{
"path": "plugins/lookup/pfsense.py",
"chars": 144767,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "plugins/module_utils/alias.py",
"chars": 4817,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018-2024, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018, Frederic Bo"
},
{
"path": "plugins/module_utils/arg_route.py",
"chars": 1107,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2024, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see"
},
{
"path": "plugins/module_utils/arg_validate.py",
"chars": 453,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2025, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see"
},
{
"path": "plugins/module_utils/default_gateway.py",
"chars": 5659,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2023, Nicolas Za"
},
{
"path": "plugins/module_utils/dhcp_server.py",
"chars": 14972,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2024, David Rosado <davidrosza0@gmail.com>\n# GNU General Public License v3.0+ "
},
{
"path": "plugins/module_utils/gateway.py",
"chars": 12186,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/haproxy_backend.py",
"chars": 8878,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/haproxy_backend_server.py",
"chars": 12572,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/interface.py",
"chars": 29239,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2021-2022, Orion"
},
{
"path": "plugins/module_utils/interface_group.py",
"chars": 6997,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/ipsec.py",
"chars": 19252,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/ipsec_p2.py",
"chars": 24011,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/ipsec_proposal.py",
"chars": 6972,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/module_base.py",
"chars": 23239,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2024, Orion Popl"
},
{
"path": "plugins/module_utils/module_config_base.py",
"chars": 2509,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2024, Orion Popl"
},
{
"path": "plugins/module_utils/nat_outbound.py",
"chars": 24297,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/nat_port_forward.py",
"chars": 19913,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2023, Orion Popl"
},
{
"path": "plugins/module_utils/openvpn_client.py",
"chars": 14806,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2020-2021, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2020, Frederic Bo"
},
{
"path": "plugins/module_utils/openvpn_override.py",
"chars": 9896,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2020-2022, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2020, Frederic Bo"
},
{
"path": "plugins/module_utils/openvpn_server.py",
"chars": 20081,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2020-2022, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2020, Frederic Bo"
},
{
"path": "plugins/module_utils/pfsense.py",
"chars": 44340,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see"
},
{
"path": "plugins/module_utils/route.py",
"chars": 6814,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/module_utils/rule.py",
"chars": 32597,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018, Frederic Bor <fr"
},
{
"path": "plugins/module_utils/rule_separator.py",
"chars": 6777,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018, Frederic Bor <fr"
},
{
"path": "plugins/module_utils/vlan.py",
"chars": 8605,
"preview": "# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0"
},
{
"path": "plugins/modules/pfsense_aggregate.py",
"chars": 46768,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_alias.py",
"chars": 2968,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "plugins/modules/pfsense_authserver_ldap.py",
"chars": 10569,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018-2024, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_authserver_radius.py",
"chars": 6265,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018-2022, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_ca.py",
"chars": 23942,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018-2024, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_cert.py",
"chars": 18815,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2021, Carlos Rodrigues <cmarodrigues@gmail.com>\n# GNU Genera"
},
{
"path": "plugins/modules/pfsense_default_gateway.py",
"chars": 2345,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "plugins/modules/pfsense_dhcp_server.py",
"chars": 5222,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2024, David Rosado <davidrosza0@gmail.com>\n# GNU General Pub"
},
{
"path": "plugins/modules/pfsense_dhcp_static.py",
"chars": 13422,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2023, Carlos Rodrigues <cmarodrigues@gmail.com>\n# GNU Genera"
},
{
"path": "plugins/modules/pfsense_dns_resolver.py",
"chars": 24834,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2021, Chris Liu <chris.liu.hk@icloud.com>\n# GNU General Publ"
},
{
"path": "plugins/modules/pfsense_gateway.py",
"chars": 3623,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "plugins/modules/pfsense_gateway_group.py",
"chars": 5106,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2026, Orion Poplawski <orion@nwra.com>\n# GNU General Public "
},
{
"path": "plugins/modules/pfsense_group.py",
"chars": 6629,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018-2020, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_haproxy_backend.py",
"chars": 4440,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_haproxy_backend_server.py",
"chars": 5078,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_interface.py",
"chars": 4249,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c"
},
{
"path": "plugins/modules/pfsense_interface_group.py",
"chars": 2391,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2022, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "plugins/modules/pfsense_ipsec.py",
"chars": 7184,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_ipsec_aggregate.py",
"chars": 26455,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_ipsec_p2.py",
"chars": 5702,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_ipsec_proposal.py",
"chars": 3584,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_log_settings.py",
"chars": 17865,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c"
},
{
"path": "plugins/modules/pfsense_nat_outbound.py",
"chars": 4558,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_nat_port_forward.py",
"chars": 4236,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c"
},
{
"path": "plugins/modules/pfsense_openvpn_client.py",
"chars": 9414,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019-2021, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_openvpn_override.py",
"chars": 4780,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2020-2022, Orion Poplawski <orion@nwra.com>\n# Copyright: (c)"
},
{
"path": "plugins/modules/pfsense_openvpn_server.py",
"chars": 14173,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019-2022, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_phpshell.py",
"chars": 3194,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2023, genofire <geno+dev@fireorbit.de>\n# GNU General Public "
},
{
"path": "plugins/modules/pfsense_rewrite_config.py",
"chars": 2387,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2023, Orion Poplawski <orion@nwra.com>\n# GNU General Public "
},
{
"path": "plugins/modules/pfsense_route.py",
"chars": 2226,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "plugins/modules/pfsense_rule.py",
"chars": 5829,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "plugins/modules/pfsense_rule_separator.py",
"chars": 2809,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_setup.py",
"chars": 29918,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General P"
},
{
"path": "plugins/modules/pfsense_shellcmd.py",
"chars": 4464,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2024, Orion Poplawski <orion@nwra.com>\n# GNU General Public "
},
{
"path": "plugins/modules/pfsense_user.py",
"chars": 10940,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2019-2024, Orion Poplawski <orion@nwra.com>\n# GNU General Pu"
},
{
"path": "plugins/modules/pfsense_vlan.py",
"chars": 2253,
"preview": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright: (c) 2018, Orion Poplawski <orion@nwra.com>\n# Copyright: (c) 2018"
},
{
"path": "setup.cfg",
"chars": 65,
"preview": "[pycodestyle]\nignore = E402,W503,W504,E741\nmax-line-length = 160\n"
},
{
"path": "tests/plays/README.md",
"chars": 526,
"preview": "# Testing pfsensible/core with plays\n\nYou must checkout this repository into a path of the form ../ansible_collections/p"
},
{
"path": "tests/plays/ansible.cfg",
"chars": 185,
"preview": "# config file for ansible -- https://ansible.com/\n# ===============================================\n\n[defaults]\ninventor"
},
{
"path": "tests/plays/host_vars/pfsense-test.yml",
"chars": 229,
"preview": "---\n# IP address of the interfaces\n# TODO - get this from ansible facts\n# \"ansible_vtnet0\": {\n# \"device"
},
{
"path": "tests/plays/hosts",
"chars": 23,
"preview": "[pfsense]\npfsense-test\n"
},
{
"path": "tests/plays/openvpn.yml",
"chars": 10679,
"preview": "---\n- hosts: pfsense\n vars:\n openvpn_aliases:\n TUNNEL_NET: 10.100.0.0/24\n LOCAL_NETS: 10.10.0.0/24 10.11.0"
},
{
"path": "tests/plays/tasks/test_interface_create.yml",
"chars": 879,
"preview": "---\n - name: \"Define interface {{ interface_args.descr }}\"\n pfsensible.core.pfsense_interface: \"{{ interface_arg"
},
{
"path": "tests/plays/tasks/test_interface_group_create.yml",
"chars": 688,
"preview": "---\n - name: \"Define interface group {{ interface_group_args.name }}\"\n pfsensible.core.pfsense_interface_group: "
},
{
"path": "tests/plays/tasks/test_interface_group_ifconfig_groups.yml",
"chars": 494,
"preview": "---\n - command: /sbin/ifconfig {{ ifname_map[ifname] }}\n changed_when: no\n register: ifconfig\n\n - set_fa"
},
{
"path": "tests/plays/tasks/test_openvpn_override_create.yml",
"chars": 1382,
"preview": "---\n - name: \"Define openvpn override {{ openvpn_override_args.name }}\"\n pfsensible.core.pfsense_openvpn_overrid"
},
{
"path": "tests/plays/tasks/test_openvpn_override_delete.yml",
"chars": 786,
"preview": "---\n - name: \"Remove openvpn override {{ openvpn_override_args.name }}\"\n pfsensible.core.pfsense_openvpn_overrid"
},
{
"path": "tests/plays/tasks/test_openvpn_override_file_exists.yml",
"chars": 639,
"preview": "---\n - wait_for:\n path: \"/var/etc/openvpn/server{{ vpnid }}/csc/{{ openvpn_override_args.name }}\"\n\n - slurp"
},
{
"path": "tests/plays/tasks/test_openvpn_server_create.yml",
"chars": 1925,
"preview": "---\n - name: \"Define openvpn server {{ openvpn_server_args.name }}\"\n pfsensible.core.pfsense_openvpn_server: \"{{"
},
{
"path": "tests/plays/tasks/test_openvpn_server_delete.yml",
"chars": 1037,
"preview": "---\n - name: \"Remove openvpn server {{ openvpn_server_args.name }}\"\n pfsensible.core.pfsense_openvpn_server:\n "
},
{
"path": "tests/plays/templates/openvpn-override.j2",
"chars": 704,
"preview": "{% if openvpn_override_args.tunnel_network is defined %}\nifconfig {{ openvpn_override_args.tunnel_network | ansible.util"
},
{
"path": "tests/plays/templates/openvpn-server-config.ovpn.j2",
"chars": 4125,
"preview": "dev ovpns{{ openvpn_server.vpnid }}\nverb {{ openvpn_server_args.verbosity_level if openvpn_server_args.verbosity_level i"
},
{
"path": "tests/sanity/ignore-2.14.txt",
"chars": 887,
"preview": "misc/pfsensible-generate-module shebang # This is not a module\nmisc/pfsense_module.py.j2 shebang # This is not a module\n"
},
{
"path": "tests/sanity/ignore-2.15.txt",
"chars": 887,
"preview": "misc/pfsensible-generate-module shebang # This is not a module\nmisc/pfsense_module.py.j2 shebang # This is not a module\n"
},
{
"path": "tests/sanity/ignore-2.16.txt",
"chars": 887,
"preview": "misc/pfsensible-generate-module shebang # This is not a module\nmisc/pfsense_module.py.j2 shebang # This is not a module\n"
},
{
"path": "tests/sanity/ignore-2.17.txt",
"chars": 887,
"preview": "misc/pfsensible-generate-module shebang # This is not a module\nmisc/pfsense_module.py.j2 shebang # This is not a module\n"
},
{
"path": "tests/unit/plugins/lookup/test_pfsense.py",
"chars": 10028,
"preview": "# Copyright: (c) 2020, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/module_utils/fixtures/pfsense_setup_config.xml",
"chars": 44626,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/module_utils/test_pfsense.py",
"chars": 2374,
"preview": "# Copyright: (c) 2022, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.g"
},
{
"path": "tests/unit/plugins/modules/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "tests/unit/plugins/modules/fixtures/2.4/pfsense_ipsec_aggregate_config.xml",
"chars": 71629,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/2.4/pfsense_ipsec_config.xml",
"chars": 69499,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/2.4/pfsense_ipsec_proposal_config.xml",
"chars": 67550,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_aggregate_config.xml",
"chars": 28646,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_alias_config.xml",
"chars": 48637,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_alias_null_config.xml",
"chars": 46160,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_authserver_config.xml",
"chars": 13150,
"preview": "<?xml version=\"1.0\"?>\n<pfsense>\n\t<version>21.7</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</op"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_ca_config.xml",
"chars": 15744,
"preview": "<?xml version=\"1.0\"?>\n<pfsense>\n\t<version>21.7</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</op"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_cert_config.xml",
"chars": 15744,
"preview": "<?xml version=\"1.0\"?>\n<pfsense>\n\t<version>21.7</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</op"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_dhcp_server_config.xml",
"chars": 5267,
"preview": "<pfsense>\n\t<version>23.3</version>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostname>pfSense</hostname>\n\t\t<dom"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_dhcp_static_config.xml",
"chars": 48873,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_dns_resolver_config_full.xml",
"chars": 6195,
"preview": "<pfsense>\n\t<version>23.3</version>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostname>pfSense</hostname>\n\t\t<dom"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_dns_resolver_config_init.xml",
"chars": 5732,
"preview": "<pfsense>\n\t<version>23.3</version>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostname>pfSense</hostname>\n\t\t<dom"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_gateway_config.xml",
"chars": 62815,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_haproxy_backend_config.xml",
"chars": 51207,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_haproxy_backend_server_config.xml",
"chars": 69173,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_interface_config.xml",
"chars": 44805,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_ipsec_aggregate_config.xml",
"chars": 72267,
"preview": "<pfsense>\n\t<version>22.2</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_ipsec_config.xml",
"chars": 73206,
"preview": "<pfsense>\n\t<version>22.2</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_ipsec_p2_config.xml",
"chars": 71629,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_ipsec_proposal_config.xml",
"chars": 67709,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_nat_outbound.xml",
"chars": 60357,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_nat_port_forward_config.xml",
"chars": 62251,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_openvpn_config.xml",
"chars": 25164,
"preview": "<?xml version=\"1.0\"?>\n<pfsense>\n\t<version>21.7</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</op"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_route_config.xml",
"chars": 63485,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_rule_config.xml",
"chars": 62928,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_rule_separator_config.xml",
"chars": 48684,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_setup_config.xml",
"chars": 44628,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_syslog_config.xml",
"chars": 1987,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<revision>\n\t\t<time>1545602758</time>\n\t\t<description>aggre"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_user_config.xml",
"chars": 11538,
"preview": "<?xml version=\"1.0\"?>\n<pfsense>\n\t<version>19.1</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</op"
},
{
"path": "tests/unit/plugins/modules/fixtures/pfsense_vlan_config.xml",
"chars": 48920,
"preview": "<pfsense>\n\t<version>18.9</version>\n\t<lastchange></lastchange>\n\t<system>\n\t\t<optimization>normal</optimization>\n\t\t<hostnam"
},
{
"path": "tests/unit/plugins/modules/pfsense_module.py",
"chars": 19877,
"preview": "# Copyright: (c) 2018 Red Hat Inc.\n# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2024, "
},
{
"path": "tests/unit/plugins/modules/test_pfsense_aggregate.py",
"chars": 18178,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_alias.py",
"chars": 17115,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_alias_null.py",
"chars": 2334,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_authserver_ldap.py",
"chars": 5756,
"preview": "# Copyright: (c) 2022, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.g"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_authserver_radius.py",
"chars": 4218,
"preview": "# Copyright: (c) 2022, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.g"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_ca.py",
"chars": 8600,
"preview": "# Copyright: (c) 2022, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.g"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_cert.py",
"chars": 12922,
"preview": "# Copyright: (c) 2025, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.g"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_dhcp_server.py",
"chars": 7786,
"preview": "# Copyright: (c) 2024, David Rosado <davidrosza0@gmail.com>\n# GNU General Public License v3.0+ (see COPYING or https://w"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_dhcp_static.py",
"chars": 6620,
"preview": "# Copyright: (c) 2023 Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gn"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_dns_resolver.py",
"chars": 7279,
"preview": "# Copyright: (c) 2024, David Rosado <davidrosza0@gmail.com>\n# Copyright: (c) 2025, Orion Poplawski <orion@nwra.com>\n# GN"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_gateway.py",
"chars": 10234,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_haproxy_backend.py",
"chars": 5364,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_haproxy_backend_server.py",
"chars": 10298,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_interface.py",
"chars": 14975,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_interface_group.py",
"chars": 5618,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# Copyright: (c) 2024, Orioni Poplawski <orion@nwra.com>\n#"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_ipsec.py",
"chars": 13960,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_ipsec_aggregate.py",
"chars": 15348,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_ipsec_p2.py",
"chars": 17975,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_ipsec_proposal.py",
"chars": 6223,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_log_settings.py",
"chars": 40277,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_nat_outbound.py",
"chars": 15522,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_nat_port_forward.py",
"chars": 12157,
"preview": "# Copyright: (c) 2018, Frederic Bor <frederic.bor@wanadoo.fr>\n# GNU General Public License v3.0+ (see COPYING or https:/"
},
{
"path": "tests/unit/plugins/modules/test_pfsense_openvpn_override.py",
"chars": 4150,
"preview": "# Copyright: (c) 2022, Orion Poplawski <orion@nwra.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.g"
}
]
// ... and 11 more files (download for full content)
About this extraction
This page contains the full source code of the pfsensible/core GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 211 files (2.8 MB), approximately 735.5k tokens, and a symbol index with 1760 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.