Skip to content

Commit

Permalink
Merge pull request #152 from scsitteam/interface_gre
Browse files Browse the repository at this point in the history
Implement GRE Interfaces
  • Loading branch information
ansibleguy authored Feb 7, 2025
2 parents 2af40df + ece9826 commit 140c7c5
Show file tree
Hide file tree
Showing 9 changed files with 355 additions and 5 deletions.
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
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

0 comments on commit 140c7c5

Please sign in to comment.