Skip to content

Commit

Permalink
Add api_info and api_modify modules.
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein committed May 24, 2022
1 parent ff66ba9 commit 2443a48
Show file tree
Hide file tree
Showing 6 changed files with 3,070 additions and 4 deletions.
2 changes: 2 additions & 0 deletions meta/runtime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ action_groups:
- api
- api_facts
- api_find_and_modify
- api_info
- api_modify
5 changes: 1 addition & 4 deletions plugins/module_utils/_api_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ def __init__(self, _dummy=None, can_disable=False, remove_value=None, default=No


def split_path(path):
parts = path.split()
if len(parts) == 1 and parts[0] == '':
parts = []
return parts
return path.split()


def join_path(path):
Expand Down
264 changes: 264 additions & 0 deletions plugins/modules/api_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright: (c) 2022, Felix Fontein <[email protected]>
# GNU General Public License v3.0+ https://www.gnu.org/licenses/gpl-3.0.txt

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = '''
---
module: api_info
author:
- "Felix Fontein (@felixfontein)"
short_description: Retrieve information from API
version_added: 2.1.0
description:
- Allows to retrieve information for a path using the API.
notes:
- Supports I(check_mode).
extends_documentation_fragment:
- community.routeros.api
options:
path:
description:
- Path to query.
- An example value is C(ip address). This is equivalent to running C(/ip address print) in the RouterOS CLI.
required: true
type: str
choices:
- caps-man aaa
- certificate settings
- interface bridge port
- interface bridge port-controller
- interface bridge port-extender
- interface bridge settings
- interface detect-internet
- interface ethernet
- interface ethernet switch
- interface ethernet switch port
- interface l2tp-server server
- interface ovpn-server server
- interface pptp-server server
- interface sstp-server server
- interface wireless align
- interface wireless cap
- interface wireless sniffer
- interface wireless snooper
- ip accounting
- ip accounting web-access
- ip address
- ip cloud
- ip cloud advanced
- ip dhcp-client
- ip dhcp-client option
- ip dhcp-server
- ip dhcp-server config
- ip dhcp-server lease
- ip dhcp-server network
- ip dns
- ip dns static
- ip firewall address-list
- ip firewall connection tracking
- ip firewall filter
- ip firewall nat
- ip firewall service-port
- ip hotspot service-port
- ip ipsec settings
- ip neighbor discovery-settings
- ip pool
- ip proxy
- ip service
- ip settings
- ip smb
- ip socks
- ip ssh
- ip tftp settings
- ip traffic-flow
- ip traffic-flow ipfix
- ip upnp
- ipv6 dhcp-client
- ipv6 firewall address-list
- ipv6 firewall filter
- ipv6 nd prefix default
- ipv6 settings
- mpls
- mpls ldp
- port firmware
- ppp aaa
- queue interface
- radius incoming
- routing bgp instance
- routing mme
- routing rip
- routing ripng
- snmp
- system clock
- system clock manual
- system identity
- system leds settings
- system note
- system ntp client
- system package update
- system routerboard settings
- system upgrade mirror
- system watchdog
- tool bandwidth-server
- tool e-mail
- tool graphing
- tool mac-server
- tool mac-server mac-winbox
- tool mac-server ping
- tool romon
- tool sms
- tool sniffer
- tool traffic-generator
- user aaa
- user group
unfiltered:
description:
- Whether to output all fields, and not just the ones supported as input for M(community.routeros.api_modify).
- Unfiltered output can contain counters and other state information.
type: bool
default: false
handle_disabled:
description:
- How to handle unset values.
- C(exclamation) prepends the keys with C(!) in the output with value C(null).
- C(null-value) uses the regular key with value C(null).
- C(omit) omits these values from the result.
type: str
choices:
- exclamation
- null-value
- omit
default: exclamation
hide_defaults:
description:
- Whether to hide default values.
type: bool
default: true
seealso:
- module: community.routeros.api
- module: community.routeros.api_modify
'''

EXAMPLES = '''
---
- name: Get IP addresses
community.routeros.api_info:
hostname: "{{ hostname }}"
password: "{{ password }}"
username: "{{ username }}"
path: ip address
register: ip_addresses
- name: Print data for IP addresses
ansible.builtin.debug:
var: ip_addresses.result
'''

RETURN = '''
---
result:
description: A list of all elements for the current path.
sample:
- '.id': '*1'
actual-interface: bridge
address: "192.168.88.1/24"
comment: defconf
disabled: false
dynamic: false
interface: bridge
invalid: false
network: 192.168.88.0
type: list
elements: dict
returned: always
'''

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native

from ansible_collections.community.routeros.plugins.module_utils.api import (
api_argument_spec,
check_has_library,
create_api,
)

from ansible_collections.community.routeros.plugins.module_utils._api_data import (
PATHS,
join_path,
split_path,
)

try:
from librouteros.exceptions import LibRouterosError
except Exception:
# Handled in api module_utils
pass


def compose_api_path(api, path):
api_path = api.path()
for p in path:
api_path = api_path.join(p)
return api_path


def main():
module_args = dict(
path=dict(type='str', required=True, choices=sorted([join_path(path) for path in PATHS if PATHS[path].fully_understood])),
unfiltered=dict(type='bool', default=False),
handle_disabled=dict(type='str', choices=['exclamation', 'null-value', 'omit'], default='exclamation'),
hide_defaults=dict(type='bool', default=True),
)
module_args.update(api_argument_spec())

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

check_has_library(module)
api = create_api(module)

path = split_path(module.params['path'])
path_info = PATHS.get(tuple(path))
if path_info is None:
module.fail_json(msg='Path /{path} is not yet supported'.format(path='/'.join(path)))

handle_disabled = module.params['handle_disabled']
hide_defaults = module.params['hide_defaults']
try:
api_path = compose_api_path(api, path)

result = []
unfiltered = module.params['unfiltered']
for entry in api_path:
if not unfiltered:
for k in list(entry):
if k == '.id':
continue
if k not in path_info.fields:
entry.pop(k)
if handle_disabled != 'omit':
for k in path_info.fields:
if k not in entry:
if handle_disabled == 'exclamation':
k = '!%s' % k
entry[k] = None
if hide_defaults:
for k, field_info in path_info.fields.items():
if field_info.default is not None and entry.get(k) == field_info.default:
entry.pop(k)
result.append(entry)

module.exit_json(result=result)
except LibRouterosError as e:
module.fail_json(msg=to_native(e))


if __name__ == '__main__':
main()
Loading

0 comments on commit 2443a48

Please sign in to comment.