Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GRE Interfaces #152

Merged
merged 3 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/modules/2_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ In most cases the returned type of this module ist a list of dictionaries.
:header: "Parameter", "Type", "Required", "Default", "Aliases", "Comment"
:widths: 15 10 10 10 10 45

"target","string","true","\-","tgt, t","What part of the running config should be queried/listed. One of: 'alias', 'rule', 'route', 'cron', 'syslog', 'package', 'unbound_general', 'unbound_acl', 'unbound_host', 'unbound_dot', 'unbound_forward', 'unbound_host_alias', 'ipsec_cert', 'shaper_pipe', 'shaper_queue', 'shaper_rule', 'monit_service', 'monit_test', 'monit_alert', 'wireguard_server', 'wireguard_peer', 'interface_lagg', 'interface_vlan', 'interface_vxlan', 'source_nat', 'frr_bfd', 'frr_bgp_general', 'frr_bgp_neighbor', 'frr_bgp_prefix_list', 'frr_bgp_community_list', 'frr_bgp_as_path', 'frr_bgp_route_map', 'frr_ospf_general', 'frr_ospf_prefix_list', 'frr_ospf_interface', 'frr_ospf_route_map', 'frr_ospf_network', 'frr_ospf3_general', 'frr_ospf3_interface', 'frr_rip', 'bind_general', 'bind_blocklist', 'bind_acl', 'bind_domain', 'bind_record', 'interface_vip', 'webproxy_general', 'webproxy_cache', 'webproxy_parent', 'webproxy_traffic', 'webproxy_forward', 'webproxy_acl', 'webproxy_icap', 'webproxy_auth', 'webproxy_remote_acl', 'webproxy_pac_proxy', 'webproxy_pac_match', 'webproxy_pac_rule', 'unbound_dnsbl', 'postfix_general', 'postfix_domain', 'postfix_recipient', 'postfix_recipientbcc', 'postfix_sender', 'postfix_senderbcc', 'postfix_sendercanonical', 'postfix_headercheck', 'postfix_address'"
"target","string","true","\-","tgt, t","What part of the running config should be queried/listed. One of: 'alias', 'rule', 'route', 'cron', 'syslog', 'package', 'unbound_general', 'unbound_acl', 'unbound_host', 'unbound_dot', 'unbound_forward', 'unbound_host_alias', 'ipsec_cert', 'shaper_pipe', 'shaper_queue', 'shaper_rule', 'monit_service', 'monit_test', 'monit_alert', 'wireguard_server', 'wireguard_peer', 'interface_lagg', 'interface_vlan', 'interface_vxlan', 'source_nat', 'frr_bfd', 'frr_bgp_general', 'frr_bgp_neighbor', 'frr_bgp_prefix_list', 'frr_bgp_community_list', 'frr_bgp_as_path', 'frr_bgp_route_map', 'frr_ospf_general', 'frr_ospf_prefix_list', 'frr_ospf_interface', 'frr_ospf_route_map', 'frr_ospf_network', 'frr_ospf3_general', 'frr_ospf3_interface', 'frr_rip', 'bind_general', 'bind_blocklist', 'bind_acl', 'bind_domain', 'bind_record', 'interface_vip', 'webproxy_general', 'webproxy_cache', 'webproxy_parent', 'webproxy_traffic', 'webproxy_forward', 'webproxy_acl', 'webproxy_icap', 'webproxy_auth', 'webproxy_remote_acl', 'webproxy_pac_proxy', 'webproxy_pac_match', 'webproxy_pac_rule', 'unbound_dnsbl', , 'interface_gre', 'postfix_general', 'postfix_domain', 'postfix_recipient', 'postfix_recipientbcc', 'postfix_sender', 'postfix_senderbcc', 'postfix_sendercanonical', 'postfix_headercheck', 'postfix_address'"

.. include:: ../_include/param_basic.rst

Expand Down
77 changes: 74 additions & 3 deletions docs/source/modules/interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ Interface
`vxlan <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_vxlan.yml>`_ |
`vip <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_vip.yml>`_ |
`lagg <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_lagg.yml>`_ |
`loopback <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_loopback.yml>`_
`loopback <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_loopback.yml>`_ |
`gre <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_gre.yml>`_

**API Docs**: `Core - Interfaces <https://docs.opnsense.org/development/api/core/interfaces.html>`_

**Service Docs**: `VLAN Docs <https://docs.opnsense.org/manual/other-interfaces.html?highlight=vlan#vlan>`_ |
`VxLAN Docs <https://docs.opnsense.org/manual/other-interfaces.html?highlight=vlan#vxlan>`_ |
`VIP Docs <https://docs.opnsense.org/manual/firewall_vip.html>`_ |
`LAGG Docs <https://docs.opnsense.org/manual/other-interfaces.html?highlight=lagg#lagg>`_ |
`Loopback Docs <https://docs.opnsense.org/manual/other-interfaces.html?highlight=loopback#loopback>`_
`GRE Docs <https://docs.opnsense.org/manual/other-interfaces.html?highlight=gre#gre>`_


Info
Expand Down Expand Up @@ -52,11 +53,16 @@ ansibleguy.opnsense.interface_loopback

This module manages Loopback configuration that can be found in the WEB-UI menu: 'Interfaces - Other Types - Loopback'

ansibleguy.opnsense.interface_gre
===================================

This module manages GRE Tunnel configuration that can be found in the WEB-UI menu: 'Interfaces - Other Types - GRE'


Contribution
************

Thanks to `@jiuka <https://github.com/jiuka>`_ for developing the :code:`interface_loopback` module!
Thanks to `@jiuka <https://github.com/jiuka>`_ for developing the :code:`interface_loopback` and :code:`interface_gre` module!

Definition
**********
Expand Down Expand Up @@ -148,6 +154,21 @@ ansibleguy.opnsense.interface_loopback
"description","string","true","\-","desc, name","The unique description used to match the configured entries to the existing ones"
"reload","boolean","false","true","\-", .. include:: ../_include/param_reload.rst

ansibleguy.opnsense.interface_gre
======================================

.. csv-table:: Definition
:header: "Parameter", "Type", "Required", "Default", "Aliases", "Comment"
:widths: 15 10 10 10 10 45

"description","string","true","\-","desc, name","The unique description used to match the configured entries to the existing ones"
"local","string","true","\-","l, local_addr","The local address or interface to use."
"remote","string","true","\-","r, remote_addr","Peer address where encapsulated gre packets will be sent."
"tunnel_local","string","true","\-","tl, tunnel_local_addr","Local gre tunnel endpoint."
"tunnel_remote","string","true","\-","tr, tunnel_remote_addr","Remote gre tunnel endpoint."
"tunnel_remote_net","integer","false","32","\-","Netmask `ipv4` or prefix `ipv6` to use for this tunnel "
"reload","boolean","false","true","\-", .. include:: ../_include/param_reload.rst


Examples
********
Expand Down Expand Up @@ -395,3 +416,53 @@ ansibleguy.opnsense.interface_loopback
ansibleguy.opnsense.interface_loopback:
description: 'MyLoopback'
state: 'absent'
ansibleguy.opnsense.interface_gre
======================================

.. code-block:: yaml
- hosts: localhost
gather_facts: no
module_defaults:
group/ansibleguy.opnsense.all:
firewall: 'opnsense.template.ansibleguy.net'
api_credential_file: '/home/guy/.secret/opn.key'
ansibleguy.opnsense.list:
target: 'interface_gre'
tasks:
- name: Example
ansibleguy.opnsense.interface_gre:
description: 'MyGRETunnel'
local: 'lan'
remote: '192.168.100.1'
tunnel_local: '10.0.0.1'
tunnel_remote: '10.0.0.2'
# tunnel_remote_net: 32
# debug: false
# state: 'present'
# reload: true
- name: Adding GRE Tunnel
ansibleguy.opnsense.interface_gre:
description: 'MyGRETunnel'
local: 'lan'
remote: '192.168.100.1'
tunnel_local: '10.0.0.1'
tunnel_remote: '10.0.0.2'
- name: Listing
ansibleguy.opnsense.list:
# target: 'interface_gre'
register: existing_entries
- name: Printing Loopbacks
ansible.builtin.debug:
var: existing_entries.data
- name: Removing GRE
ansibleguy.opnsense.interface_gre:
description: 'MyGRETunnel'
state: 'absent'
1 change: 1 addition & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ action_groups:
- ansibleguy.opnsense.interface_vip
- ansibleguy.opnsense.interface_lagg
- ansibleguy.opnsense.interface_loopback
- ansibleguy.opnsense.interface_gre
frr:
- ansibleguy.opnsense.frr_diagnostic
- ansibleguy.opnsense.frr_general
Expand Down
52 changes: 52 additions & 0 deletions plugins/module_utils/main/interface_gre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from ansible.module_utils.basic import AnsibleModule

from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.api import \
Session
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.helper.main import \
validate_int_fields
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.cls import BaseModule


class Gre(BaseModule):
FIELD_ID = 'description'
CMDS = {
'add': 'addItem',
'del': 'delItem',
'set': 'setItem',
'search': 'get',
'toggle': 'toggleItem',
}
API_KEY_PATH = 'gre.gre'
API_MOD = 'interfaces'
API_CONT = 'gre_settings'
FIELDS_CHANGE = ['local', 'remote', 'tunnel_local', 'tunnel_remote', 'tunnel_remote_net']
FIELDS_ALL = [FIELD_ID]
FIELDS_ALL.extend(FIELDS_CHANGE)
FIELDS_TRANSLATE = {
'description': 'descr',
'local': 'local-addr',
'remote': 'remote-addr',
'tunnel_local': 'tunnel-local-addr',
'tunnel_remote': 'tunnel-remote-addr',
'tunnel_remote_net': 'tunnel-remote-net',
}
FIELDS_TYPING = {
'bool': [],
'list': [],
'select': [],
'int': ['tunnel_remote_net'],
}
INT_VALIDATIONS = {
'tunnel_remote_net': {'min': 1, 'max': 128},
}
EXIST_ATTR = 'gre'

def __init__(self, module: AnsibleModule, result: dict, session: Session = None):
BaseModule.__init__(self=self, m=module, r=result, s=session)
self.gre = {}

def check(self) -> None:
if self.p['state'] == 'present':
validate_int_fields(module=self.m, data=self.p, field_minmax=self.INT_VALIDATIONS)

self._base_check()
82 changes: 82 additions & 0 deletions plugins/modules/interface_gre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright: (C) 2024, AnsibleGuy <[email protected]>
# GNU General Public License v3.0+ (see https://www.gnu.org/licenses/gpl-3.0.txt)

from ansible.module_utils.basic import AnsibleModule

from ansible_collections.ansibleguy.opnsense.plugins.module_utils.base.handler import \
module_dependency_error, MODULE_EXCEPTIONS

try:
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.helper.wrapper import module_wrapper
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.defaults.main import \
OPN_MOD_ARGS, STATE_ONLY_MOD_ARG, RELOAD_MOD_ARG
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.main.interface_gre import Gre

except MODULE_EXCEPTIONS:
module_dependency_error()


# DOCUMENTATION = 'https://opnsense.ansibleguy.net/modules/interface.html'
# EXAMPLES = 'https://opnsense.ansibleguy.net/modules/interface.html'


def run_module():
module_args = dict(
description=dict(
type='str', required=True, aliases=['desc'],
description='The unique description used to match the configured entries to the existing ones.',
),
local=dict(
type='str', required=False, aliases=['l', 'local_addr'],
description='The local address or interface to use.',
),
remote=dict(
type='str', required=False, aliases=['r', 'remote_addr'],
description='Peer address where encapsulated gre packets will be sent.',
),
tunnel_local=dict(
type='str', required=False, aliases=['tl', 'tunnel_local_addr'],
description='Local gre tunnel endpoint.',
),
tunnel_remote=dict(
type='str', required=False, aliases=['tr', 'tunnel_remote_addr'],
description='Remote gre tunnel endpoint.',
),
tunnel_remote_net=dict(
type='int', required=False, default=32,
description="Netmask 'ipv4' or prefix 'ipv6' to use for this tunnel",
),
**RELOAD_MOD_ARG,
**STATE_ONLY_MOD_ARG,
**OPN_MOD_ARGS,
)

result = dict(
changed=False,
diff={
'before': {},
'after': {},
}
)

module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True,
required_if=[
('state', 'present', ('local', 'remote', 'tunnel_local', 'tunnel_remote')),
],
)

module_wrapper(Gre(module=module, result=result))
module.exit_json(**result)


def main():
run_module()


if __name__ == '__main__':
main()
6 changes: 5 additions & 1 deletion plugins/modules/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
'interface_lagg', 'interface_loopback', 'unbound_dnsbl', 'dhcp_reservation', 'acme_general', 'acme_account',
'acme_validation', 'acme_action', 'acme_certificate', 'postfix_general', 'postfix_domain', 'postfix_recipient',
'postfix_recipientbcc', 'postfix_sender', 'postfix_senderbcc', 'postfix_sendercanonical', 'postfix_headercheck',
'postfix_address', 'dhcp_subnet', 'dhcp_general',
'postfix_address', 'dhcp_subnet', 'dhcp_general', 'interface_gre',
]


Expand Down Expand Up @@ -186,6 +186,10 @@ def run_module():
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.main.interface_loopback import \
Loopback as Target_Obj

elif target == 'interface_gre':
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.main.interface_gre import \
Gre as Target_Obj

elif target == 'source_nat':
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.main.source_nat import \
SNat as Target_Obj
Expand Down
1 change: 1 addition & 0 deletions scripts/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ run_test 'interface_vxlan' 1
run_test 'interface_vip' 1
run_test 'interface_lagg' 1
run_test 'interface_loopback' 1
run_test 'interface_gre' 1
run_test 'source_nat' 1
run_test 'frr_diagnostic' 1
run_test 'frr_general' 1
Expand Down
8 changes: 8 additions & 0 deletions tests/1_cleanup.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---

- name: Cleaning up firewall config

Check warning on line 3 in tests/1_cleanup.yml

View workflow job for this annotation

GitHub Actions / lint

complexity[play]

Maximum tasks allowed in a play is 100.
hosts: localhost
gather_facts: no
module_defaults:
Expand Down Expand Up @@ -239,6 +239,14 @@
device: 'lagg0'
state: 'absent'

- name: Cleanup GRE interfaces
ansibleguy.opnsense.interface_gre:
description: "{{ item }}"
state: 'absent'
loop:
- 'ANSIBLE_TEST_1_1'
- 'ANSIBLE_TEST_1_2'

- name: Cleanup source-nat
ansibleguy.opnsense.source_nat:
description: "{{ item }}"
Expand Down
Loading
Loading