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

Feature: Add module for Loopback interfaces #108

Merged
merged 1 commit into from
Oct 25, 2024
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
71 changes: 65 additions & 6 deletions docs/source/modules/interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ Interface

**TESTS**: `vlan <https://github.com/ansibleguy/collection_opnsense/blob/latest/tests/interface_vlan.yml>`_ |
`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>`_
`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>`_

**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>`_
`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>`_


Info
Expand All @@ -38,12 +42,16 @@ ansibleguy.opnsense.interface_vip

This module manages VIP configuration that can be found in the WEB-UI menu: 'Interfaces - Virtual IPs - Settings'


ansibleguy.opnsense.interface_lagg
===================================

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

ansibleguy.opnsense.interface_loopback
===================================

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


Definition
**********
Expand Down Expand Up @@ -102,7 +110,7 @@ ansibleguy.opnsense.interface_vip


ansibleguy.opnsense.interface_lagg
=================================
==================================

.. warning::

Expand All @@ -125,6 +133,16 @@ ansibleguy.opnsense.interface_lagg
"description","string","true","\-","desc, name","The description used to match the configured entries to the existing ones"
"reload","boolean","false","true","\-", .. include:: ../_include/param_reload.rst

ansibleguy.opnsense.interface_loopback
======================================

.. 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"
"reload","boolean","false","true","\-", .. include:: ../_include/param_reload.rst


Examples
********
Expand Down Expand Up @@ -280,7 +298,7 @@ ansibleguy.opnsense.interface_vip
state: 'absent'

ansibleguy.opnsense.interface_lagg
=================================
==================================

.. code-block:: yaml

Expand Down Expand Up @@ -327,7 +345,48 @@ ansibleguy.opnsense.interface_lagg
var: existing_entries.data

- name: Removing LAGG
ansibleguy.opnsense.interface_vip:
ansibleguy.opnsense.interface_lagg:
device: lagg0
match_fields: ['device']
state: 'absent'

ansibleguy.opnsense.interface_loopback
======================================

.. 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_loopback'

tasks:
- name: Example
ansibleguy.opnsense.interface_loopback:
description: 'MyLoopback'
# debug: false
# state: 'present'
# reload: true

- name: Adding Loopback
ansibleguy.opnsense.interface_loopback:
description: 'MyLoopback'

- name: Listing
ansibleguy.opnsense.list:
# target: 'interface_loopback'
register: existing_entries

- name: Printing Loopbacks
ansible.builtin.debug:
var: existing_entries.data

- name: Removing Loopback
ansibleguy.opnsense.interface_loopback:
description: 'MyLoopback'
state: 'absent'
1 change: 1 addition & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ action_groups:
- ansibleguy.opnsense.interface_vxlan
- ansibleguy.opnsense.interface_vip
- ansibleguy.opnsense.interface_lagg
- ansibleguy.opnsense.interface_loopback
frr:
- ansibleguy.opnsense.frr_diagnostic
- ansibleguy.opnsense.frr_general
Expand Down
30 changes: 30 additions & 0 deletions plugins/module_utils/main/interface_loopback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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.base.cls import BaseModule


class Loopback(BaseModule):
FIELD_ID = 'description'
CMDS = {
'add': 'addItem',
'del': 'delItem',
'set': 'setItem',
'search': 'get',
}
API_KEY_PATH = 'loopback.loopback'
API_MOD = 'interfaces'
API_CONT = 'loopback_settings'
API_CMD_REL = 'reconfigure'
FIELDS_CHANGE = []
FIELDS_ALL = [FIELD_ID]
FIELDS_TYPING = {}
EXIST_ATTR = 'interface'

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

def check(self) -> None:
self._base_check()
58 changes: 58 additions & 0 deletions plugins/modules/interface_loopback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/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)

# template to be copied to implement new modules

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_MOD_ARG, RELOAD_MOD_ARG
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.main.interface_loopback import Loopback

except MODULE_EXCEPTIONS:
module_dependency_error()


# DOCUMENTATION = 'https://opnsense.ansibleguy.net/en/latest/modules/interface_loopback.html'
# EXAMPLES = 'https://opnsense.ansibleguy.net/en/latest/modules/interface_loopback.html'


def run_module():
module_args = dict(
description=dict(type='str', required=True, aliases=['desc']),
**RELOAD_MOD_ARG,
**STATE_MOD_ARG,
**OPN_MOD_ARGS,
)

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

module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True,
)

module_wrapper(Loopback(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 @@ -36,7 +36,7 @@
'ipsec_child', 'ipsec_vti', 'ipsec_auth_local', 'ipsec_auth_remote', 'frr_general', 'unbound_general',
'unbound_acl', 'ids_general', 'ids_policy', 'ids_rule', 'ids_ruleset', 'ids_user_rule', 'ids_policy_rule',
'openvpn_instance', 'openvpn_static_key', 'openvpn_client_override', 'dhcrelay_destination', 'dhcrelay_relay',
'interface_lagg',
'interface_lagg', 'interface_loopback',
]


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

elif target == 'interface_loopback':
from ansible_collections.ansibleguy.opnsense.plugins.module_utils.main.interface_loopback import \
Loopback 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 @@ -87,6 +87,7 @@ run_test 'interface_vlan' 1
run_test 'interface_vxlan' 1
run_test 'interface_vip' 1
run_test 'interface_lagg' 1
run_test 'interface_loopback' 1
run_test 'source_nat' 1
run_test 'frr_diagnostic' 1
run_test 'frr_general' 1
Expand Down
90 changes: 90 additions & 0 deletions tests/interface_loopback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---

- name: Testing Loopback
hosts: localhost
gather_facts: no
module_defaults:
group/ansibleguy.opnsense.all:
firewall: "{{ lookup('ansible.builtin.env', 'TEST_FIREWALL') }}"
api_credential_file: "{{ lookup('ansible.builtin.env', 'TEST_API_KEY') }}"
ssl_verify: false

ansibleguy.opnsense.list:
target: 'interface_loopback'

tasks:
- name: Listing
ansibleguy.opnsense.list:
register: opn_pre1
failed_when: >
'data' not in opn_pre1 or
opn_pre1.data | length != 0

- name: Removing - does not exist
ansibleguy.opnsense.interface_loopback:
description: 'DOESNOTEXIST'
state: 'absent'
register: opn_pre2
failed_when: >
opn_pre2.failed or
opn_pre2.changed

- name: Adding 1
ansibleguy.opnsense.interface_loopback:
description: 'ANSIBLE_TEST_1_1'
register: opn1
failed_when: >
opn1.failed or
not opn1.changed

- name: Adding 2
ansibleguy.opnsense.interface_loopback:
description: 'ANSIBLE_TEST_1_2'
register: opn2
failed_when: >
opn2.failed or
not opn2.changed

- name: Adding 2 - nothing changed
ansibleguy.opnsense.interface_loopback:
description: 'ANSIBLE_TEST_1_2'
register: opn3
failed_when: >
opn3.failed or
opn3.changed
when: not ansible_check_mode

- name: Removing 2
ansibleguy.opnsense.interface_loopback:
description: 'ANSIBLE_TEST_1_2'
state: 'absent'
register: opn4
failed_when: >
opn4.failed or
not opn4.changed
when: not ansible_check_mode

- name: Listing
ansibleguy.opnsense.list:
register: opn5
failed_when: >
'data' not in opn5 or
opn5.data | length != 1
when: not ansible_check_mode

- name: Cleanup
ansibleguy.opnsense.interface_loopback:
description: "{{ item }}"
state: 'absent'
loop:
- 'ANSIBLE_TEST_1_1'
- 'ANSIBLE_TEST_1_2'
when: not ansible_check_mode

- name: Listing
ansibleguy.opnsense.list:
register: opn_clean1
failed_when: >
'data' not in opn_clean1 or
opn_clean1.data | length != 0
when: not ansible_check_mode
Loading