Remove incidental_vyos_static_route (#72024)

* Add explicit tests for required_together suboptions

* ci_complete ci_coverage

* Remove incidental_vyos_static_route

* ci_complete ci_coverage

* Add explicit coverage of suboptions required_if

* ci_complete ci_coverage

* Remove incidental_vyos_logging

* ci_complete ci_coverage
This commit is contained in:
Matt Martz 2020-09-30 15:38:12 -05:00 committed by GitHub
parent 64d9ccb965
commit 9081b22868
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 64 additions and 1257 deletions

View file

@ -20,6 +20,28 @@ def main():
'mapping': {
'type': 'dict',
},
'required_together': {
'required_together': [['thing', 'other']],
'type': 'list',
'elements': 'dict',
'options': {
'thing': {},
'other': {},
'another': {},
}
},
'required_if': {
'required_if': (
('thing', 'foo', ('other',), True),
),
'type': 'list',
'elements': 'dict',
'options': {
'thing': {},
'other': {},
'another': {},
}
},
},
required_if=(
('state', 'present', ('path', 'content'), True),

View file

@ -1,6 +1,5 @@
- argspec:
state: absent
register: argspec_simple_good
- argspec:
state: present
@ -10,12 +9,10 @@
- argspec:
state: present
path: foo
register: argspec_required_if_good1
- argspec:
state: present
content: foo
register: argspec_required_if_good2
- argspec:
state: present
@ -54,13 +51,48 @@
register: argspec_bad_mapping_list
ignore_errors: true
- argspec:
required_together:
- thing: foo
other: bar
another: baz
- argspec:
required_together:
- another: baz
- argspec:
required_together:
- thing: foo
register: argspec_required_together_fail
ignore_errors: true
- argspec:
required_together:
- thing: foo
other: bar
- argspec:
required_if:
- thing: bar
- argspec:
required_if:
- thing: foo
other: bar
- argspec:
required_if:
- thing: foo
register: argpsec_required_if_fail
ignore_errors: true
- assert:
that:
- argspec_simple_good is successful
- argspec_required_if_fail is failed
- argspec_required_if_good1 is successful
- argspec_required_if_good2 is successful
- argspec_mutually_exclusive_fail is failed
- argspec_good_mapping is successful
- >-
argspec_good_mapping.mapping == {'foo': 'bar'}
@ -73,3 +105,7 @@
- argspec_bad_mapping_string is failed
- argspec_bad_mapping_int is failed
- argspec_bad_mapping_list is failed
- argspec_required_together_fail is failed
- argpsec_required_if_fail is failed

View file

@ -1,2 +0,0 @@
shippable/vyos/incidental
network/vyos

View file

@ -1,3 +0,0 @@
---
testcase: "*"
test_items: []

View file

@ -1,22 +0,0 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
register: test_cases
delegate_to: localhost
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test case (connection=ansible.netcommon.network_cli)
include: "{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
- name: run test case (connection=local)
include: "{{ test_case_to_run }} ansible_connection=local"
with_first_found: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

@ -1,2 +0,0 @@
---
- {include: cli.yaml, tags: ['cli']}

View file

@ -1,126 +0,0 @@
---
- debug: msg="START cli/basic.yaml on connection={{ ansible_connection }}"
- name: set-up logging
vyos.vyos.vyos_logging:
dest: console
facility: all
level: info
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set system syslog console facility all level info" in result.commands'
- name: set-up logging again (idempotent)
vyos.vyos.vyos_logging:
dest: console
facility: all
level: info
state: present
register: result
- assert:
that:
- 'result.changed == false'
- name: file logging
vyos.vyos.vyos_logging:
dest: file
name: test
facility: all
level: notice
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set system syslog file test facility all level notice" in result.commands'
- name: file logging again (idempotent)
vyos.vyos.vyos_logging:
dest: file
name: test
facility: all
level: notice
state: present
register: result
- assert:
that:
- 'result.changed == false'
- name: delete logging
vyos.vyos.vyos_logging:
dest: file
name: test
facility: all
level: notice
state: absent
register: result
- assert:
that:
- 'result.changed == true'
- '"delete system syslog file test facility all level notice" in result.commands'
- name: delete logging again (idempotent)
vyos.vyos.vyos_logging:
dest: file
name: test
facility: all
level: notice
state: absent
register: result
- assert:
that:
- 'result.changed == false'
- name: Add logging collections
vyos.vyos.vyos_logging:
aggregate:
- {dest: file, name: test1, facility: all, level: info}
- {dest: file, name: test2, facility: news, level: debug}
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set system syslog file test1 facility all level info" in result.commands'
- '"set system syslog file test2 facility news level debug" in result.commands'
- name: Add and remove logging collections with overrides
vyos.vyos.vyos_logging:
aggregate:
- {dest: console, facility: all, level: info}
- {dest: file, name: test1, facility: all, level: info, state: absent}
- {dest: console, facility: daemon, level: warning}
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"delete system syslog file test1 facility all level info" in result.commands'
- '"set system syslog console facility daemon level warning" in result.commands'
- name: Remove logging collections
vyos.vyos.vyos_logging:
aggregate:
- {dest: console, facility: all, level: info}
- {dest: console, facility: daemon, level: warning}
- {dest: file, name: test2, facility: news, level: debug}
state: absent
register: result
- assert:
that:
- 'result.changed == true'
- '"delete system syslog console facility all level info" in result.commands'
- '"delete system syslog console facility daemon level warning" in result.commands'
- '"delete system syslog file test2 facility news level debug" in result.commands'

View file

@ -1,39 +0,0 @@
---
- debug: msg="START vyos cli/net_logging.yaml on connection={{ ansible_connection }}"
# Add minimal testcase to check args are passed correctly to
# implementation module and module run is successful.
- name: delete logging - setup
ansible.netcommon.net_logging:
dest: file
name: test
facility: all
level: notice
state: absent
register: result
- name: file logging using platform agnostic module
ansible.netcommon.net_logging:
dest: file
name: test
facility: all
level: notice
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set system syslog file test facility all level notice" in result.commands'
- name: delete logging - teardown
ansible.netcommon.net_logging:
dest: file
name: test
facility: all
level: notice
state: absent
register: result
- debug: msg="END vyos cli/net_logging.yaml on connection={{ ansible_connection }}"

View file

@ -1,2 +0,0 @@
shippable/vyos/incidental
network/vyos

View file

@ -1,3 +0,0 @@
---
testcase: "*"
test_items: []

View file

@ -1,22 +0,0 @@
---
- name: collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
register: test_cases
delegate_to: localhost
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test case (connection=ansible.netcommon.network_cli)
include: "{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
- name: run test case (connection=local)
include: "{{ test_case_to_run }} ansible_connection=local"
with_first_found: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

@ -1,2 +0,0 @@
---
- {include: cli.yaml, tags: ['cli']}

View file

@ -1,120 +0,0 @@
---
- debug: msg="START cli/basic.yaml on connection={{ ansible_connection }}"
- name: create static route
vyos.vyos.vyos_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64" in result.commands'
- name: create static route again (idempotent)
vyos.vyos.vyos_static_route:
prefix: 172.24.0.0
mask: 24
next_hop: 192.168.42.64
state: present
register: result
- assert:
that:
- 'result.changed == false'
- name: modify admin distance of static route
vyos.vyos.vyos_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
admin_distance: 1
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64 distance 1" in result.commands'
- name: modify admin distance of static route again (idempotent)
vyos.vyos.vyos_static_route:
prefix: 172.24.0.0
mask: 24
next_hop: 192.168.42.64
admin_distance: 1
state: present
register: result
- assert:
that:
- 'result.changed == false'
- name: delete static route
vyos.vyos.vyos_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
admin_distance: 1
state: absent
register: result
- assert:
that:
- 'result.changed == true'
- '"delete protocols static route 172.24.0.0/24" in result.commands'
- name: delete static route again (idempotent)
vyos.vyos.vyos_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
admin_distance: 1
state: absent
register: result
- assert:
that:
- 'result.changed == false'
- name: Add static route collections
vyos.vyos.vyos_static_route:
aggregate:
- {prefix: 172.24.1.0/24, next_hop: 192.168.42.64}
- {prefix: 172.24.2.0, mask: 24, next_hop: 192.168.42.64}
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set protocols static route 172.24.1.0/24 next-hop 192.168.42.64" in result.commands'
- '"set protocols static route 172.24.2.0/24 next-hop 192.168.42.64" in result.commands'
- name: Add and remove static route collections with overrides
vyos.vyos.vyos_static_route:
aggregate:
- {prefix: 172.24.1.0/24, next_hop: 192.168.42.64}
- {prefix: 172.24.2.0/24, next_hop: 192.168.42.64, state: absent}
- {prefix: 172.24.3.0/24, next_hop: 192.168.42.64}
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"delete protocols static route 172.24.2.0/24" in result.commands'
- '"set protocols static route 172.24.3.0/24 next-hop 192.168.42.64" in result.commands'
- name: Remove static route collections
vyos.vyos.vyos_static_route:
aggregate:
- {prefix: 172.24.1.0/24, next_hop: 192.168.42.64}
- {prefix: 172.24.3.0/24, next_hop: 192.168.42.64}
state: absent
register: result
- assert:
that:
- 'result.changed == true'
- '"delete protocols static route 172.24.1.0/24" in result.commands'
- '"delete protocols static route 172.24.3.0/24" in result.commands'

View file

@ -1,33 +0,0 @@
---
- debug: msg="START vyos cli/net_static_route.yaml on connection={{ ansible_connection }}"
# Add minimal testcase to check args are passed correctly to
# implementation module and module run is successful.
- name: delete static route - setup
ansible.netcommon.net_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
state: absent
register: result
- name: create static route using platform agnostic module
ansible.netcommon.net_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
state: present
register: result
- assert:
that:
- 'result.changed == true'
- '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64" in result.commands'
- name: delete static route - teardown
ansible.netcommon.net_static_route:
prefix: 172.24.0.0/24
next_hop: 192.168.42.64
state: absent
register: result
- debug: msg="END vyos cli/net_static_route.yaml on connection={{ ansible_connection }}"

View file

@ -261,10 +261,6 @@ test/support/network-integration/collections/ansible_collections/vyos/vyos/plugi
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_config.py metaclass-boilerplate
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py future-import-boilerplate
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_facts.py metaclass-boilerplate
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_logging.py future-import-boilerplate
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_logging.py metaclass-boilerplate
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_static_route.py future-import-boilerplate
test/support/network-integration/collections/ansible_collections/vyos/vyos/plugins/modules/vyos_static_route.py metaclass-boilerplate
test/support/windows-integration/plugins/modules/async_status.ps1 pslint!skip
test/support/windows-integration/plugins/modules/setup.ps1 pslint!skip
test/support/windows-integration/plugins/modules/win_copy.ps1 pslint!skip

View file

@ -1,30 +0,0 @@
# (c) 2017, Ansible Inc,
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.ansible.netcommon.plugins.action.net_base import (
ActionModule as _ActionModule,
)
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
result = super(ActionModule, self).run(tmp, task_vars)
del tmp # tmp no longer has any effect
return result

View file

@ -1,31 +0,0 @@
# (c) 2017, Ansible Inc,
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.ansible.netcommon.plugins.action.net_base import (
ActionModule as _ActionModule,
)
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
result = super(ActionModule, self).run(tmp, task_vars)
del tmp # tmp no longer has any effect
return result

View file

@ -1,110 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2017, Ansible by Red Hat, inc
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["deprecated"],
"supported_by": "network",
}
DOCUMENTATION = """module: net_logging
author: Ganesh Nalawade (@ganeshrn)
short_description: Manage logging on network devices
description:
- This module provides declarative management of logging on network devices.
deprecated:
removed_in: '2.13'
alternative: Use platform-specific "[netos]_logging" module
why: Updated modules released with more functionality
extends_documentation_fragment:
- ansible.netcommon.network_agnostic
options:
dest:
description:
- Destination of the logs.
choices:
- console
- host
name:
description:
- If value of C(dest) is I(host) it indicates file-name the host name to be notified.
facility:
description:
- Set logging facility.
level:
description:
- Set logging severity levels.
aggregate:
description: List of logging definitions.
purge:
description:
- Purge logging not defined in the I(aggregate) parameter.
default: false
state:
description:
- State of the logging configuration.
default: present
choices:
- present
- absent
"""
EXAMPLES = """
- name: configure console logging
net_logging:
dest: console
facility: any
level: critical
- name: remove console logging configuration
net_logging:
dest: console
state: absent
- name: configure host logging
net_logging:
dest: host
name: 192.0.2.1
facility: kernel
level: critical
- name: Configure file logging using aggregate
net_logging:
dest: file
aggregate:
- name: test-1
facility: pfe
level: critical
- name: test-2
facility: kernel
level: emergency
- name: Delete file logging using aggregate
net_logging:
dest: file
aggregate:
- name: test-1
facility: pfe
level: critical
- name: test-2
facility: kernel
level: emergency
state: absent
"""
RETURN = """
commands:
description: The list of configuration mode commands to send to the device
returned: always, except for the platforms that use Netconf transport to manage the device.
type: list
sample:
- logging console critical
"""

View file

@ -1,98 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2017, Ansible by Red Hat, inc
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["deprecated"],
"supported_by": "network",
}
DOCUMENTATION = """module: net_static_route
author: Ricardo Carrillo Cruz (@rcarrillocruz)
short_description: Manage static IP routes on network appliances (routers, switches
et. al.)
description:
- This module provides declarative management of static IP routes on network appliances
(routers, switches et. al.).
deprecated:
removed_in: '2.13'
alternative: Use platform-specific "[netos]_static_route" module
why: Updated modules released with more functionality
extends_documentation_fragment:
- ansible.netcommon.network_agnostic
options:
prefix:
description:
- Network prefix of the static route.
required: true
mask:
description:
- Network prefix mask of the static route.
required: true
next_hop:
description:
- Next hop IP of the static route.
required: true
admin_distance:
description:
- Admin distance of the static route.
aggregate:
description: List of static route definitions
purge:
description:
- Purge static routes not defined in the I(aggregate) parameter.
default: false
state:
description:
- State of the static route configuration.
default: present
choices:
- present
- absent
"""
EXAMPLES = """
- name: configure static route
net_static_route:
prefix: 192.168.2.0
mask: 255.255.255.0
next_hop: 10.0.0.1
- name: remove configuration
net_static_route:
prefix: 192.168.2.0
mask: 255.255.255.0
next_hop: 10.0.0.1
state: absent
- name: configure aggregates of static routes
net_static_route:
aggregate:
- { prefix: 192.168.2.0, mask: 255.255.255.0, next_hop: 10.0.0.1 }
- { prefix: 192.168.3.0, mask: 255.255.255.0, next_hop: 10.0.2.1 }
- name: Remove static route collections
net_static_route:
aggregate:
- { prefix: 172.24.1.0/24, next_hop: 192.168.42.64 }
- { prefix: 172.24.3.0/24, next_hop: 192.168.42.64 }
state: absent
"""
RETURN = """
commands:
description: The list of configuration mode commands to send to the device
returned: always
type: list
sample:
- ip route 192.168.2.0/24 10.0.0.1
"""

View file

@ -1,300 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2017, Ansible by Red Hat, inc
#
# This file is part of Ansible by Red Hat
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["preview"],
"supported_by": "network",
}
DOCUMENTATION = """module: vyos_logging
author: Trishna Guha (@trishnaguha)
short_description: Manage logging on network devices
description:
- This module provides declarative management of logging on Vyatta Vyos devices.
notes:
- Tested against VyOS 1.1.8 (helium).
- This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html).
options:
dest:
description:
- Destination of the logs.
choices:
- console
- file
- global
- host
- user
name:
description:
- If value of C(dest) is I(file) it indicates file-name, for I(user) it indicates
username and for I(host) indicates the host name to be notified.
facility:
description:
- Set logging facility.
level:
description:
- Set logging severity levels.
aggregate:
description: List of logging definitions.
state:
description:
- State of the logging configuration.
default: present
choices:
- present
- absent
extends_documentation_fragment:
- vyos.vyos.vyos
"""
EXAMPLES = """
- name: configure console logging
vyos_logging:
dest: console
facility: all
level: crit
- name: remove console logging configuration
vyos_logging:
dest: console
state: absent
- name: configure file logging
vyos_logging:
dest: file
name: test
facility: local3
level: err
- name: Add logging aggregate
vyos_logging:
aggregate:
- { dest: file, name: test1, facility: all, level: info }
- { dest: file, name: test2, facility: news, level: debug }
state: present
- name: Remove logging aggregate
vyos_logging:
aggregate:
- { dest: console, facility: all, level: info }
- { dest: console, facility: daemon, level: warning }
- { dest: file, name: test2, facility: news, level: debug }
state: absent
"""
RETURN = """
commands:
description: The list of configuration mode commands to send to the device
returned: always
type: list
sample:
- set system syslog global facility all level notice
"""
import re
from copy import deepcopy
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
remove_default_spec,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import (
get_config,
load_config,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import (
vyos_argument_spec,
)
def spec_to_commands(updates, module):
commands = list()
want, have = updates
for w in want:
dest = w["dest"]
name = w["name"]
facility = w["facility"]
level = w["level"]
state = w["state"]
del w["state"]
if state == "absent" and w in have:
if w["name"]:
commands.append(
"delete system syslog {0} {1} facility {2} level {3}".format(
dest, name, facility, level
)
)
else:
commands.append(
"delete system syslog {0} facility {1} level {2}".format(
dest, facility, level
)
)
elif state == "present" and w not in have:
if w["name"]:
commands.append(
"set system syslog {0} {1} facility {2} level {3}".format(
dest, name, facility, level
)
)
else:
commands.append(
"set system syslog {0} facility {1} level {2}".format(
dest, facility, level
)
)
return commands
def config_to_dict(module):
data = get_config(module)
obj = []
for line in data.split("\n"):
if line.startswith("set system syslog"):
match = re.search(r"set system syslog (\S+)", line, re.M)
dest = match.group(1)
if dest == "host":
match = re.search(r"host (\S+)", line, re.M)
name = match.group(1)
elif dest == "file":
match = re.search(r"file (\S+)", line, re.M)
name = match.group(1)
elif dest == "user":
match = re.search(r"user (\S+)", line, re.M)
name = match.group(1)
else:
name = None
if "facility" in line:
match = re.search(r"facility (\S+)", line, re.M)
facility = match.group(1)
if "level" in line:
match = re.search(r"level (\S+)", line, re.M)
level = match.group(1).strip("'")
obj.append(
{
"dest": dest,
"name": name,
"facility": facility,
"level": level,
}
)
return obj
def map_params_to_obj(module, required_if=None):
obj = []
aggregate = module.params.get("aggregate")
if aggregate:
for item in aggregate:
for key in item:
if item.get(key) is None:
item[key] = module.params[key]
module._check_required_if(required_if, item)
obj.append(item.copy())
else:
if module.params["dest"] not in ("host", "file", "user"):
module.params["name"] = None
obj.append(
{
"dest": module.params["dest"],
"name": module.params["name"],
"facility": module.params["facility"],
"level": module.params["level"],
"state": module.params["state"],
}
)
return obj
def main():
""" main entry point for module execution
"""
element_spec = dict(
dest=dict(
type="str", choices=["console", "file", "global", "host", "user"]
),
name=dict(type="str"),
facility=dict(type="str"),
level=dict(type="str"),
state=dict(default="present", choices=["present", "absent"]),
)
aggregate_spec = deepcopy(element_spec)
# remove default in aggregate spec, to handle common arguments
remove_default_spec(aggregate_spec)
argument_spec = dict(
aggregate=dict(type="list", elements="dict", options=aggregate_spec),
)
argument_spec.update(element_spec)
argument_spec.update(vyos_argument_spec)
required_if = [
("dest", "host", ["name", "facility", "level"]),
("dest", "file", ["name", "facility", "level"]),
("dest", "user", ["name", "facility", "level"]),
("dest", "console", ["facility", "level"]),
("dest", "global", ["facility", "level"]),
]
module = AnsibleModule(
argument_spec=argument_spec,
required_if=required_if,
supports_check_mode=True,
)
warnings = list()
result = {"changed": False}
if warnings:
result["warnings"] = warnings
want = map_params_to_obj(module, required_if=required_if)
have = config_to_dict(module)
commands = spec_to_commands((want, have), module)
result["commands"] = commands
if commands:
commit = not module.check_mode
load_config(module, commands, commit=commit)
result["changed"] = True
module.exit_json(**result)
if __name__ == "__main__":
main()

View file

@ -1,302 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2017, Ansible by Red Hat, inc
#
# This file is part of Ansible by Red Hat
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["deprecated"],
"supported_by": "network",
}
DOCUMENTATION = """module: vyos_static_route
author: Trishna Guha (@trishnaguha)
short_description: Manage static IP routes on Vyatta VyOS network devices
description:
- This module provides declarative management of static IP routes on Vyatta VyOS network
devices.
deprecated:
removed_in: '2.13'
alternative: vyos_static_routes
why: Updated modules released with more functionality.
notes:
- Tested against VyOS 1.1.8 (helium).
- This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html).
options:
prefix:
description:
- Network prefix of the static route. C(mask) param should be ignored if C(prefix)
is provided with C(mask) value C(prefix/mask).
type: str
mask:
description:
- Network prefix mask of the static route.
type: str
next_hop:
description:
- Next hop IP of the static route.
type: str
admin_distance:
description:
- Admin distance of the static route.
type: int
aggregate:
description: List of static route definitions
type: list
state:
description:
- State of the static route configuration.
default: present
choices:
- present
- absent
type: str
extends_documentation_fragment:
- vyos.vyos.vyos
"""
EXAMPLES = """
- name: configure static route
vyos_static_route:
prefix: 192.168.2.0
mask: 24
next_hop: 10.0.0.1
- name: configure static route prefix/mask
vyos_static_route:
prefix: 192.168.2.0/16
next_hop: 10.0.0.1
- name: remove configuration
vyos_static_route:
prefix: 192.168.2.0
mask: 16
next_hop: 10.0.0.1
state: absent
- name: configure aggregates of static routes
vyos_static_route:
aggregate:
- { prefix: 192.168.2.0, mask: 24, next_hop: 10.0.0.1 }
- { prefix: 192.168.3.0, mask: 16, next_hop: 10.0.2.1 }
- { prefix: 192.168.3.0/16, next_hop: 10.0.2.1 }
- name: Remove static route collections
vyos_static_route:
aggregate:
- { prefix: 172.24.1.0/24, next_hop: 192.168.42.64 }
- { prefix: 172.24.3.0/24, next_hop: 192.168.42.64 }
state: absent
"""
RETURN = """
commands:
description: The list of configuration mode commands to send to the device
returned: always
type: list
sample:
- set protocols static route 192.168.2.0/16 next-hop 10.0.0.1
"""
import re
from copy import deepcopy
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
remove_default_spec,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import (
get_config,
load_config,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import (
vyos_argument_spec,
)
def spec_to_commands(updates, module):
commands = list()
want, have = updates
for w in want:
prefix = w["prefix"]
mask = w["mask"]
next_hop = w["next_hop"]
admin_distance = w["admin_distance"]
state = w["state"]
del w["state"]
if state == "absent" and w in have:
commands.append(
"delete protocols static route %s/%s" % (prefix, mask)
)
elif state == "present" and w not in have:
cmd = "set protocols static route %s/%s next-hop %s" % (
prefix,
mask,
next_hop,
)
if admin_distance != "None":
cmd += " distance %s" % (admin_distance)
commands.append(cmd)
return commands
def config_to_dict(module):
data = get_config(module)
obj = []
for line in data.split("\n"):
if line.startswith("set protocols static route"):
match = re.search(r"static route (\S+)", line, re.M)
prefix = match.group(1).split("/")[0]
mask = match.group(1).split("/")[1]
if "next-hop" in line:
match_hop = re.search(r"next-hop (\S+)", line, re.M)
next_hop = match_hop.group(1).strip("'")
match_distance = re.search(r"distance (\S+)", line, re.M)
if match_distance is not None:
admin_distance = match_distance.group(1)[1:-1]
else:
admin_distance = None
if admin_distance is not None:
obj.append(
{
"prefix": prefix,
"mask": mask,
"next_hop": next_hop,
"admin_distance": admin_distance,
}
)
else:
obj.append(
{
"prefix": prefix,
"mask": mask,
"next_hop": next_hop,
"admin_distance": "None",
}
)
return obj
def map_params_to_obj(module, required_together=None):
obj = []
aggregate = module.params.get("aggregate")
if aggregate:
for item in aggregate:
for key in item:
if item.get(key) is None:
item[key] = module.params[key]
module._check_required_together(required_together, item)
d = item.copy()
if "/" in d["prefix"]:
d["mask"] = d["prefix"].split("/")[1]
d["prefix"] = d["prefix"].split("/")[0]
if "admin_distance" in d:
d["admin_distance"] = str(d["admin_distance"])
obj.append(d)
else:
prefix = module.params["prefix"].strip()
if "/" in prefix:
mask = prefix.split("/")[1]
prefix = prefix.split("/")[0]
else:
mask = module.params["mask"].strip()
next_hop = module.params["next_hop"].strip()
admin_distance = str(module.params["admin_distance"])
state = module.params["state"]
obj.append(
{
"prefix": prefix,
"mask": mask,
"next_hop": next_hop,
"admin_distance": admin_distance,
"state": state,
}
)
return obj
def main():
""" main entry point for module execution
"""
element_spec = dict(
prefix=dict(type="str"),
mask=dict(type="str"),
next_hop=dict(type="str"),
admin_distance=dict(type="int"),
state=dict(default="present", choices=["present", "absent"]),
)
aggregate_spec = deepcopy(element_spec)
aggregate_spec["prefix"] = dict(required=True)
# remove default in aggregate spec, to handle common arguments
remove_default_spec(aggregate_spec)
argument_spec = dict(
aggregate=dict(type="list", elements="dict", options=aggregate_spec),
)
argument_spec.update(element_spec)
argument_spec.update(vyos_argument_spec)
required_one_of = [["aggregate", "prefix"]]
required_together = [["prefix", "next_hop"]]
mutually_exclusive = [["aggregate", "prefix"]]
module = AnsibleModule(
argument_spec=argument_spec,
required_one_of=required_one_of,
required_together=required_together,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True,
)
warnings = list()
result = {"changed": False}
if warnings:
result["warnings"] = warnings
want = map_params_to_obj(module, required_together=required_together)
have = config_to_dict(module)
commands = spec_to_commands((want, have), module)
result["commands"] = commands
if commands:
commit = not module.check_mode
load_config(module, commands, commit=commit)
result["changed"] = True
module.exit_json(**result)
if __name__ == "__main__":
main()