Skip to content

Commit 1fe1b07

Browse files
authored
feat(frontend_server): add extaddr parameter validation (#5)
Add validation for the extaddr parameter to accept: - Standard pfSense options: any_ipv4, localhost_ipv4, wan_ipv4, lan_ipv4, any_ipv6, localhost_ipv6, wan_ipv6, lan_ipv6 - Interface-specific options: opt<N>_ipv4 or opt<N>_ipv6 - Custom IPv4 and IPv6 addresses Includes unit tests and updated documentation.
1 parent 0927f60 commit 1fe1b07

File tree

5 files changed

+374
-8
lines changed

5 files changed

+374
-8
lines changed

docs/modules/pfsense_haproxy_frontend_server.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,55 @@ Manage pfSense HAProxy frontend servers
1111
| Parameter | Type | Required | Default | Choices | Description |
1212
|-----------|------|----------|---------|---------|-------------|
1313
| frontend | str | yes | - | - | The frontend name. |
14-
| extaddr | str | no | - | - | External address to bind to. |
14+
| extaddr | str | no | - | See description | External address to bind to. Can be a standard pfSense address option, an interface-specific option, or a custom IP address. Standard options: `any_ipv4`, `localhost_ipv4`, `wan_ipv4`, `lan_ipv4`, `any_ipv6`, `localhost_ipv6`, `wan_ipv6`, `lan_ipv6`. Interface options: `opt<N>_ipv4` or `opt<N>_ipv6` where N is the interface number (e.g., `opt1_ipv4`, `opt2_ipv6`). Custom addresses: Any valid IPv4 or IPv6 address. |
1515
| extaddr_port | int | no | - | - | External port to bind to. |
1616
| extaddr_ssl | str | no | - | - | SSL configuration for external address. |
1717
| state | str | no | present | present, absent | State in which to leave the frontend server |
1818

1919
## Examples
2020

2121
```yaml
22-
- name: Add frontend server binding
22+
- name: Add frontend server binding with custom IPv4 address
2323
pfsensible.haproxy.pfsense_haproxy_frontend_server:
2424
frontend: web-frontend
25-
extaddr: 0.0.0.0
25+
extaddr: 192.168.1.100
2626
extaddr_port: 443
2727
extaddr_ssl: "yes"
2828
state: present
2929

30+
- name: Bind to any IPv4 address
31+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
32+
frontend: web-frontend
33+
extaddr: any_ipv4
34+
extaddr_port: 80
35+
state: present
36+
37+
- name: Bind to WAN interface address
38+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
39+
frontend: web-frontend
40+
extaddr: wan_ipv4
41+
extaddr_port: 443
42+
extaddr_ssl: "yes"
43+
state: present
44+
45+
- name: Bind to optional interface (e.g., LAB network)
46+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
47+
frontend: internal-frontend
48+
extaddr: opt1_ipv4
49+
extaddr_port: 8080
50+
state: present
51+
52+
- name: Bind to IPv6 address
53+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
54+
frontend: web-frontend
55+
extaddr: any_ipv6
56+
extaddr_port: 443
57+
state: present
58+
3059
- name: Remove frontend server binding
3160
pfsensible.haproxy.pfsense_haproxy_frontend_server:
3261
frontend: web-frontend
33-
extaddr: 0.0.0.0
62+
extaddr: wan_ipv4
3463
extaddr_port: 443
3564
state: absent
3665
```

plugins/module_utils/haproxy_frontend_server.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,25 @@
55

66
from __future__ import absolute_import, division, print_function
77
__metaclass__ = type
8+
import re
9+
import socket
810
from ansible_collections.pfsensible.core.plugins.module_utils.module_base import PFSenseModuleBase
911

12+
# Standard pfSense address choices for external addresses
13+
EXTADDR_STANDARD_CHOICES = [
14+
'any_ipv4',
15+
'localhost_ipv4',
16+
'wan_ipv4',
17+
'lan_ipv4',
18+
'any_ipv6',
19+
'localhost_ipv6',
20+
'wan_ipv6',
21+
'lan_ipv6',
22+
]
23+
24+
# Pattern for interface-specific options: opt<digits>_ipv4 or opt<digits>_ipv6
25+
EXTADDR_INTERFACE_PATTERN = re.compile(r'^opt\d+_ipv[46]$')
26+
1027
HAPROXY_FRONTEND_SERVER_ARGUMENT_SPEC = dict(
1128
state=dict(default='present', choices=['present', 'absent']),
1229
frontend=dict(required=True, type='str'),
@@ -54,9 +71,46 @@ def _params_to_obj(self):
5471

5572
return obj
5673

74+
def _validate_extaddr(self, extaddr):
75+
"""Validate the extaddr parameter value."""
76+
if extaddr is None:
77+
return # Not provided, skip validation
78+
79+
# Check standard choices
80+
if extaddr in EXTADDR_STANDARD_CHOICES:
81+
return
82+
83+
# Check interface pattern (opt<N>_ipv4 or opt<N>_ipv6)
84+
if EXTADDR_INTERFACE_PATTERN.match(extaddr):
85+
return
86+
87+
# Check if valid IPv4 address
88+
try:
89+
socket.inet_pton(socket.AF_INET, extaddr)
90+
return
91+
except socket.error:
92+
pass
93+
94+
# Check if valid IPv6 address
95+
try:
96+
socket.inet_pton(socket.AF_INET6, extaddr)
97+
return
98+
except socket.error:
99+
pass
100+
101+
# Invalid value
102+
self.module.fail_json(
103+
msg="Invalid extaddr value '{0}'. Must be one of: {1}, "
104+
"an interface option (opt<N>_ipv4 or opt<N>_ipv6), "
105+
"or a valid IPv4/IPv6 address.".format(
106+
extaddr, ', '.join(EXTADDR_STANDARD_CHOICES)))
107+
57108
def _validate_params(self):
58109
""" do some extra checks on input parameters """
59110

111+
# validate extaddr value
112+
self._validate_extaddr(self.params.get('extaddr'))
113+
60114
# get the frontend
61115
self.frontend = self._find_frontend(self.params['frontend'])
62116
if self.frontend is None:

plugins/modules/pfsense_haproxy_frontend_server.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@
2626
required: true
2727
type: str
2828
extaddr:
29-
description: External address to bind to.
29+
description:
30+
- External address to bind to.
31+
- Can be a standard pfSense address option, an interface-specific option, or a custom IP address.
32+
- "Standard options: any_ipv4, localhost_ipv4, wan_ipv4, lan_ipv4, any_ipv6, localhost_ipv6, wan_ipv6, lan_ipv6"
33+
- "Interface options: opt<N>_ipv4 or opt<N>_ipv6 where N is the interface number (e.g., opt1_ipv4, opt2_ipv6)"
34+
- "Custom addresses: Any valid IPv4 or IPv6 address (e.g., 192.168.1.1, 2001:db8::1)"
3035
required: false
3136
type: str
3237
extaddr_port:
@@ -45,18 +50,47 @@
4550
"""
4651

4752
EXAMPLES = """
48-
- name: Add frontend server binding
53+
- name: Add frontend server binding with custom IPv4 address
4954
pfsensible.haproxy.pfsense_haproxy_frontend_server:
5055
frontend: web-frontend
51-
extaddr: 0.0.0.0
56+
extaddr: 192.168.1.100
5257
extaddr_port: 443
5358
extaddr_ssl: "yes"
5459
state: present
5560
61+
- name: Bind to any IPv4 address
62+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
63+
frontend: web-frontend
64+
extaddr: any_ipv4
65+
extaddr_port: 80
66+
state: present
67+
68+
- name: Bind to WAN interface address
69+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
70+
frontend: web-frontend
71+
extaddr: wan_ipv4
72+
extaddr_port: 443
73+
extaddr_ssl: "yes"
74+
state: present
75+
76+
- name: Bind to optional interface (e.g., LAB network)
77+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
78+
frontend: internal-frontend
79+
extaddr: opt1_ipv4
80+
extaddr_port: 8080
81+
state: present
82+
83+
- name: Bind to IPv6 address
84+
pfsensible.haproxy.pfsense_haproxy_frontend_server:
85+
frontend: web-frontend
86+
extaddr: any_ipv6
87+
extaddr_port: 443
88+
state: present
89+
5690
- name: Remove frontend server binding
5791
pfsensible.haproxy.pfsense_haproxy_frontend_server:
5892
frontend: web-frontend
59-
extaddr: 0.0.0.0
93+
extaddr: wan_ipv4
6094
extaddr_port: 443
6195
state: absent
6296
"""
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<pfsense>
2+
<version>18.9</version>
3+
<lastchange></lastchange>
4+
<revision>
5+
<time>1545602758</time>
6+
<description>test</description>
7+
<username></username>
8+
</revision>
9+
<system>
10+
<optimization>normal</optimization>
11+
<hostname>pfSense</hostname>
12+
<domain>acme.com</domain>
13+
</system>
14+
<interfaces>
15+
<wan>
16+
<enable></enable>
17+
<if>vmx0</if>
18+
<descr>wan</descr>
19+
<ipaddr>192.168.240.137</ipaddr>
20+
<subnet>24</subnet>
21+
</wan>
22+
<lan>
23+
<enable></enable>
24+
<if>vmx1</if>
25+
<descr>lan</descr>
26+
<ipaddr>192.168.1.242</ipaddr>
27+
<subnet>24</subnet>
28+
</lan>
29+
</interfaces>
30+
<installedpackages>
31+
<haproxy>
32+
<ha_backends>
33+
<item>
34+
<name>test-frontend</name>
35+
<id>100</id>
36+
<type>http</type>
37+
<a_extaddr>
38+
<item>
39+
<name>'wan_ipv4_443'</name>
40+
<extaddr>wan_ipv4</extaddr>
41+
<extaddr_port>443</extaddr_port>
42+
<extaddr_ssl>yes</extaddr_ssl>
43+
</item>
44+
</a_extaddr>
45+
</item>
46+
</ha_backends>
47+
<ha_pools>
48+
<item>
49+
<name>test-backend</name>
50+
<id>101</id>
51+
</item>
52+
</ha_pools>
53+
</haproxy>
54+
</installedpackages>
55+
</pfsense>

0 commit comments

Comments
 (0)