Handle common argument in aggregate parameter for vyos module (#28182)
* Handle common agrument in aggregate parameter for vyos module * Add supoort to set parameter in aggregate to it's respctive top level argument if value not provided in aggregate. * Aggregate argument spec validation * Documentation for aggregate * Fix unit test failure
This commit is contained in:
parent
3f9d6aa0f1
commit
38c0b581c3
18 changed files with 353 additions and 165 deletions
|
@ -87,6 +87,24 @@ EXAMPLES = """
|
|||
name: ge-0/0/1
|
||||
description: test-interface
|
||||
enabled: False
|
||||
|
||||
- name: Create interface using aggregate
|
||||
net_interface:
|
||||
aggregate:
|
||||
- name: ge-0/0/1
|
||||
description: test-interface-1
|
||||
- name: ge-0/0/2
|
||||
description: test-interface-2
|
||||
speed: 1g
|
||||
duplex: full
|
||||
mtu: 512
|
||||
|
||||
- name: Delete interface using aggregate
|
||||
junos_interface:
|
||||
aggregate:
|
||||
- name: ge-0/0/1
|
||||
- name: ge-0/0/2
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
|
|
@ -70,6 +70,18 @@ EXAMPLES = """
|
|||
name: bond0
|
||||
state: absent
|
||||
|
||||
- name: Create aggregate of linkagg definitions
|
||||
net_linkagg:
|
||||
aggregate:
|
||||
- { name: bond0, members: [eth1] }
|
||||
- { name: bond1, members: [eth2] }
|
||||
|
||||
- name: Remove aggregate of linkagg definitions
|
||||
net_linkagg:
|
||||
aggregate:
|
||||
- name: bond0
|
||||
- name: bond1
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
|
|
@ -58,6 +58,20 @@ EXAMPLES = """
|
|||
net_lldp_interface:
|
||||
name: eth1
|
||||
state: absent
|
||||
|
||||
- name: Create aggregate of LLDP interface configurations
|
||||
net_lldp_interface:
|
||||
aggregate:
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: present
|
||||
|
||||
- name: Delete aggregate of LLDP interface configurations
|
||||
net_lldp_interface:
|
||||
aggregate:
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
|
|
@ -55,6 +55,19 @@ EXAMPLES = """
|
|||
net_l3_interface:
|
||||
name: eth0
|
||||
state: absent
|
||||
|
||||
- name: Set IP addresses on aggregate
|
||||
net_l3_interface:
|
||||
aggregate:
|
||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||
|
||||
- name: Remove IP addresses on aggregate
|
||||
net_l3_interface:
|
||||
aggregate:
|
||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
|
|
@ -70,6 +70,13 @@ EXAMPLES = """
|
|||
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 = """
|
||||
|
|
|
@ -98,9 +98,11 @@ EXAMPLES = """
|
|||
name: ansible
|
||||
sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
|
||||
state: present
|
||||
|
||||
- name: remove all users except admin
|
||||
net_user:
|
||||
purge: yes
|
||||
|
||||
- name: set multiple users to privilege level 15
|
||||
net_user:
|
||||
aggregate:
|
||||
|
@ -108,6 +110,7 @@ EXAMPLES = """
|
|||
- name: netend
|
||||
privilege: 15
|
||||
state: present
|
||||
|
||||
- name: Change Password for User netop
|
||||
net_user:
|
||||
name: netop
|
||||
|
|
|
@ -93,6 +93,26 @@ EXAMPLES = """
|
|||
speed: 100
|
||||
mtu: 256
|
||||
duplex: full
|
||||
|
||||
- name: Set interface using aggregate
|
||||
vyos_interface:
|
||||
aggregate:
|
||||
- { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512}
|
||||
- { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256}
|
||||
|
||||
- name: Disable interface on aggregate
|
||||
net_interface:
|
||||
aggregate:
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
enabled: False
|
||||
|
||||
- name: Delete interface using aggregate
|
||||
net_interface:
|
||||
aggregate:
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -108,12 +128,13 @@ commands:
|
|||
"""
|
||||
import re
|
||||
|
||||
from copy import deepcopy
|
||||
from time import sleep
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.network_common import conditional
|
||||
from ansible.module_utils.network_common import conditional, remove_default_spec
|
||||
from ansible.module_utils.vyos import load_config, get_config
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
||||
|
@ -213,40 +234,19 @@ def map_config_to_obj(module):
|
|||
|
||||
def map_params_to_obj(module):
|
||||
obj = []
|
||||
|
||||
params = ['speed', 'description', 'duplex', 'mtu']
|
||||
aggregate = module.params.get('aggregate')
|
||||
|
||||
if aggregate:
|
||||
for c in aggregate:
|
||||
d = c.copy()
|
||||
if 'name' not in d:
|
||||
module.fail_json(msg="missing required arguments: %s" % 'name')
|
||||
|
||||
for item in params:
|
||||
if item not in d:
|
||||
d[item] = None
|
||||
|
||||
if d.get('description') is None:
|
||||
d['description'] = DEFAULT_DESCRIPTION
|
||||
|
||||
if not d.get('state'):
|
||||
d['state'] = module.params['state']
|
||||
|
||||
if d.get('enabled') is None:
|
||||
d['enabled'] = module.params['enabled']
|
||||
for item in aggregate:
|
||||
for key in item:
|
||||
if item.get(key) is None:
|
||||
item[key] = module.params[key]
|
||||
|
||||
d = item.copy()
|
||||
if d['enabled']:
|
||||
d['disable'] = False
|
||||
else:
|
||||
d['disable'] = True
|
||||
|
||||
if d.get('delay') is None:
|
||||
d['delay'] = module.params['delay']
|
||||
|
||||
if d.get('speed'):
|
||||
d['speed'] = str(d['speed'])
|
||||
|
||||
obj.append(d)
|
||||
else:
|
||||
params = {
|
||||
|
@ -300,7 +300,7 @@ def check_declarative_intent_params(module, want, result):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
element_spec = dict(
|
||||
name=dict(),
|
||||
description=dict(default=DEFAULT_DESCRIPTION),
|
||||
speed=dict(),
|
||||
|
@ -308,11 +308,21 @@ def main():
|
|||
duplex=dict(choices=['full', 'half', 'auto']),
|
||||
enabled=dict(default=True, type='bool'),
|
||||
delay=dict(default=10, type='int'),
|
||||
aggregate=dict(type='list'),
|
||||
state=dict(default='present',
|
||||
choices=['present', 'absent', 'up', 'down'])
|
||||
)
|
||||
|
||||
aggregate_spec = deepcopy(element_spec)
|
||||
aggregate_spec['name'] = 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 = [['name', 'aggregate']]
|
||||
|
|
|
@ -45,10 +45,6 @@ options:
|
|||
- IPv6 of the L3 interface.
|
||||
aggregate:
|
||||
description: List of L3 interfaces definitions
|
||||
purge:
|
||||
description:
|
||||
- Purge L3 interfaces not defined in the aggregate parameter.
|
||||
default: no
|
||||
state:
|
||||
description:
|
||||
- State of the L3 interface configuration.
|
||||
|
@ -66,6 +62,19 @@ EXAMPLES = """
|
|||
vyos_l3_interface:
|
||||
name: eth0
|
||||
state: absent
|
||||
|
||||
- name: Set IP addresses on aggregate
|
||||
vyos_l3_interface:
|
||||
aggregate:
|
||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||
|
||||
- name: Remove IP addresses on aggregate
|
||||
vyos_l3_interface:
|
||||
aggregate:
|
||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -76,7 +85,10 @@ commands:
|
|||
sample:
|
||||
- set interfaces ethernet eth0 address '192.168.0.1/24'
|
||||
"""
|
||||
from copy import deepcopy
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network_common import remove_default_spec
|
||||
from ansible.module_utils.vyos import load_config, run_commands
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
||||
|
@ -153,18 +165,14 @@ def map_config_to_obj(module):
|
|||
def map_params_to_obj(module):
|
||||
obj = []
|
||||
|
||||
if 'aggregate' in module.params and module.params['aggregate']:
|
||||
for c in module.params['aggregate']:
|
||||
d = c.copy()
|
||||
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]
|
||||
|
||||
if 'ipv4' not in d:
|
||||
d['ipv4'] = None
|
||||
if 'ipv6' not in d:
|
||||
d['ipv6'] = None
|
||||
if 'state' not in d:
|
||||
d['state'] = module.params['state']
|
||||
|
||||
obj.append(d)
|
||||
obj.append(item.copy())
|
||||
else:
|
||||
obj.append({
|
||||
'name': module.params['name'],
|
||||
|
@ -179,16 +187,25 @@ def map_params_to_obj(module):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
element_spec = dict(
|
||||
name=dict(),
|
||||
ipv4=dict(),
|
||||
ipv6=dict(),
|
||||
aggregate=dict(type='list'),
|
||||
purge=dict(default=False, type='bool'),
|
||||
state=dict(default='present',
|
||||
choices=['present', 'absent'])
|
||||
)
|
||||
|
||||
aggregate_spec = deepcopy(element_spec)
|
||||
aggregate_spec['name'] = 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 = [['name', 'aggregate']]
|
||||
|
|
|
@ -49,10 +49,6 @@ options:
|
|||
- List of members of the link aggregation group.
|
||||
aggregate:
|
||||
description: List of link aggregation definitions.
|
||||
purge:
|
||||
description:
|
||||
- Purge link aggregation groups not defined in the aggregates parameter.
|
||||
default: no
|
||||
state:
|
||||
description:
|
||||
- State of the link aggregation group.
|
||||
|
@ -73,6 +69,18 @@ EXAMPLES = """
|
|||
name: bond0
|
||||
state: absent
|
||||
|
||||
- name: Create aggregate of linkagg definitions
|
||||
vyos_linkagg:
|
||||
aggregate:
|
||||
- { name: bond0, members: [eth1] }
|
||||
- { name: bond1, members: [eth2] }
|
||||
|
||||
- name: Remove aggregate of linkagg definitions
|
||||
vyos_linkagg:
|
||||
aggregate:
|
||||
- name: bond0
|
||||
- name: bond1
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -85,7 +93,10 @@ commands:
|
|||
- set interfaces ethernet eth0 bond-group 'bond0'
|
||||
- set interfaces ethernet eth1 bond-group 'bond0'
|
||||
"""
|
||||
from copy import deepcopy
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network_common import remove_default_spec
|
||||
from ansible.module_utils.vyos import load_config, run_commands
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
||||
|
@ -173,17 +184,14 @@ def map_config_to_obj(module):
|
|||
|
||||
def map_params_to_obj(module):
|
||||
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]
|
||||
|
||||
if 'aggregate' in module.params and module.params['aggregate']:
|
||||
for c in module.params['aggregate']:
|
||||
d = c.copy()
|
||||
|
||||
if 'state' not in d:
|
||||
d['state'] = module.params['state']
|
||||
if 'mode' not in d:
|
||||
d['mode'] = module.params['mode']
|
||||
|
||||
obj.append(d)
|
||||
obj.append(item.copy())
|
||||
else:
|
||||
obj.append({
|
||||
'name': module.params['name'],
|
||||
|
@ -198,25 +206,35 @@ def map_params_to_obj(module):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
element_spec = dict(
|
||||
name=dict(),
|
||||
mode=dict(choices=['802.3ad', 'active-backup', 'broadcast',
|
||||
'round-robin', 'transmit-load-balance',
|
||||
'adaptive-load-balance', 'xor-hash', 'on'],
|
||||
default='802.3ad'),
|
||||
members=dict(type='list'),
|
||||
aggregate=dict(type='list'),
|
||||
purge=dict(default=False, type='bool'),
|
||||
state=dict(default='present',
|
||||
choices=['present', 'absent', 'up', 'down'])
|
||||
)
|
||||
|
||||
aggregate_spec = deepcopy(element_spec)
|
||||
aggregate_spec['name'] = 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 = [['name', 'aggregate']]
|
||||
mutually_exclusive = [['name', 'aggregate']]
|
||||
module = AnsibleModule(argument_spec=argument_spec,
|
||||
required_one_of=required_one_of,
|
||||
mutually_exclusive=mutually_exclusive,
|
||||
supports_check_mode=True)
|
||||
|
||||
warnings = list()
|
||||
|
|
|
@ -78,7 +78,6 @@ def main():
|
|||
"""
|
||||
argument_spec = dict(
|
||||
interfaces=dict(type='list'),
|
||||
purge=dict(default=False, type='bool'),
|
||||
state=dict(default='present',
|
||||
choices=['present', 'absent',
|
||||
'enabled', 'disabled'])
|
||||
|
|
|
@ -39,10 +39,6 @@ options:
|
|||
- Name of the interface LLDP should be configured on.
|
||||
aggregate:
|
||||
description: List of interfaces LLDP should be configured on.
|
||||
purge:
|
||||
description:
|
||||
- Purge interfaces not defined in the aggregate parameter.
|
||||
default: no
|
||||
state:
|
||||
description:
|
||||
- State of the LLDP configuration.
|
||||
|
@ -64,7 +60,21 @@ EXAMPLES = """
|
|||
|
||||
- name: Disable LLDP globally
|
||||
net_lldp_interface:
|
||||
state: lldp
|
||||
state: disabled
|
||||
|
||||
- name: Create aggregate of LLDP interface configurations
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: present
|
||||
|
||||
- name: Delete aggregate of LLDP interface configurations
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
|
@ -76,7 +86,10 @@ commands:
|
|||
- set service lldp eth1
|
||||
- set service lldp eth2 disable
|
||||
"""
|
||||
from copy import deepcopy
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network_common import remove_default_spec
|
||||
from ansible.module_utils.vyos import get_config, load_config
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
||||
|
@ -142,14 +155,14 @@ def map_config_to_obj(module):
|
|||
def map_params_to_obj(module):
|
||||
obj = []
|
||||
|
||||
if module.params['aggregate']:
|
||||
for i in module.params['aggregate']:
|
||||
d = i.copy()
|
||||
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]
|
||||
|
||||
if 'state' not in d:
|
||||
d['state'] = module.params['state']
|
||||
|
||||
obj.append(d)
|
||||
obj.append(item.copy())
|
||||
else:
|
||||
obj.append({'name': module.params['name'], 'state': module.params['state']})
|
||||
|
||||
|
@ -159,16 +172,26 @@ def map_params_to_obj(module):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
element_spec = dict(
|
||||
name=dict(),
|
||||
aggregate=dict(type='list'),
|
||||
purge=dict(default=False, type='bool'),
|
||||
state=dict(default='present',
|
||||
choices=['present', 'absent',
|
||||
'enabled', 'disabled'])
|
||||
)
|
||||
|
||||
aggregate_spec = deepcopy(element_spec)
|
||||
aggregate_spec['name'] = 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 = [['name', 'aggregate']]
|
||||
mutually_exclusive = [['name', 'aggregate']]
|
||||
|
||||
|
|
|
@ -50,10 +50,6 @@ options:
|
|||
- Set logging severity levels.
|
||||
aggregate:
|
||||
description: List of logging definitions.
|
||||
purge:
|
||||
description:
|
||||
- Purge logging not defined in the aggregate parameter.
|
||||
default: no
|
||||
state:
|
||||
description:
|
||||
- State of the logging configuration.
|
||||
|
@ -67,16 +63,33 @@ EXAMPLES = """
|
|||
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 = """
|
||||
|
@ -90,7 +103,10 @@ commands:
|
|||
|
||||
import re
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network_common import remove_default_spec
|
||||
from ansible.module_utils.vyos import get_config, load_config
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
||||
|
@ -160,21 +176,18 @@ def config_to_dict(module):
|
|||
return obj
|
||||
|
||||
|
||||
def map_params_to_obj(module):
|
||||
def map_params_to_obj(module, required_if=None):
|
||||
obj = []
|
||||
|
||||
if 'aggregate' in module.params and module.params['aggregate']:
|
||||
for c in module.params['aggregate']:
|
||||
d = c.copy()
|
||||
if d['dest'] not in ('host', 'file', 'user'):
|
||||
d['name'] = None
|
||||
else:
|
||||
pass
|
||||
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]
|
||||
|
||||
if 'state' not in d:
|
||||
d['state'] = module.params['state']
|
||||
|
||||
obj.append(d)
|
||||
module._check_required_if(required_if, item)
|
||||
obj.append(item.copy())
|
||||
|
||||
else:
|
||||
if module.params['dest'] not in ('host', 'file', 'user'):
|
||||
|
@ -194,16 +207,25 @@ def map_params_to_obj(module):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
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=dict(type='list'),
|
||||
purge=dict(default=False, type='bool')
|
||||
)
|
||||
|
||||
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']),
|
||||
|
@ -221,7 +243,7 @@ def main():
|
|||
result = {'changed': False}
|
||||
if warnings:
|
||||
result['warnings'] = warnings
|
||||
want = map_params_to_obj(module)
|
||||
want = map_params_to_obj(module, required_if=required_if)
|
||||
have = config_to_dict(module)
|
||||
|
||||
commands = spec_to_commands((want, have), module)
|
||||
|
|
|
@ -50,10 +50,6 @@ options:
|
|||
- Admin distance of the static route.
|
||||
aggregate:
|
||||
description: List of static route definitions
|
||||
purge:
|
||||
description:
|
||||
- Purge static routes not defined in the aggregates parameter.
|
||||
default: no
|
||||
state:
|
||||
description:
|
||||
- State of the static route configuration.
|
||||
|
@ -67,22 +63,32 @@ EXAMPLES = """
|
|||
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 = """
|
||||
|
@ -93,10 +99,12 @@ commands:
|
|||
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.module_utils.network_common import remove_default_spec
|
||||
from ansible.module_utils.vyos import get_config, load_config
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
||||
|
@ -156,20 +164,23 @@ def config_to_dict(module):
|
|||
return obj
|
||||
|
||||
|
||||
def map_params_to_obj(module):
|
||||
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]
|
||||
|
||||
if 'aggregate' in module.params and module.params['aggregate']:
|
||||
for c in module.params['aggregate']:
|
||||
d = c.copy()
|
||||
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 'state' not in d:
|
||||
d['state'] = module.params['state']
|
||||
if 'admin_distance' not in d:
|
||||
d['admin_distance'] = str(module.params['admin_distance'])
|
||||
if 'admin_distance' in d:
|
||||
d['admin_distance'] = str(d['admin_distance'])
|
||||
|
||||
obj.append(d)
|
||||
else:
|
||||
|
@ -197,16 +208,27 @@ def map_params_to_obj(module):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
element_spec = dict(
|
||||
prefix=dict(type='str'),
|
||||
mask=dict(type='str'),
|
||||
next_hop=dict(type='str'),
|
||||
admin_distance=dict(type='int'),
|
||||
aggregate=dict(type='list'),
|
||||
purge=dict(type='bool'),
|
||||
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)
|
||||
|
||||
argument_spec.update(vyos_argument_spec)
|
||||
required_one_of = [['aggregate', 'prefix']]
|
||||
required_together = [['prefix', 'next_hop']]
|
||||
|
@ -215,6 +237,7 @@ def main():
|
|||
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()
|
||||
|
@ -223,7 +246,7 @@ def main():
|
|||
result = {'changed': False}
|
||||
if warnings:
|
||||
result['warnings'] = warnings
|
||||
want = map_params_to_obj(module)
|
||||
want = map_params_to_obj(module, required_together=required_together)
|
||||
have = config_to_dict(module)
|
||||
|
||||
commands = spec_to_commands((want, have), module)
|
||||
|
|
|
@ -127,9 +127,11 @@ commands:
|
|||
|
||||
import re
|
||||
|
||||
from copy import deepcopy
|
||||
from functools import partial
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network_common import remove_default_spec
|
||||
from ansible.module_utils.vyos import get_config, load_config
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.vyos import vyos_argument_spec, check_args
|
||||
|
@ -215,13 +217,6 @@ def get_param_value(key, item, module):
|
|||
if not item.get(key):
|
||||
value = module.params[key]
|
||||
|
||||
# if key does exist, do a type check on it to validate it
|
||||
else:
|
||||
value_type = module.argument_spec[key].get('type', 'str')
|
||||
type_checker = module._CHECK_ARGUMENT_TYPES_DISPATCHER[value_type]
|
||||
type_checker(item[key])
|
||||
value = item[key]
|
||||
|
||||
# validate the param value (if validator func exists)
|
||||
validator = globals().get('validate_%s' % key)
|
||||
if all((value, validator)):
|
||||
|
@ -231,21 +226,17 @@ def get_param_value(key, item, module):
|
|||
|
||||
|
||||
def map_params_to_obj(module):
|
||||
users = module.params['users']
|
||||
if not users:
|
||||
aggregate = module.params['aggregate']
|
||||
if not aggregate:
|
||||
if not module.params['name'] and module.params['purge']:
|
||||
return list()
|
||||
elif not module.params['name']:
|
||||
module.fail_json(msg='username is required')
|
||||
else:
|
||||
aggregate = [{'name': module.params['name']}]
|
||||
else:
|
||||
aggregate = list()
|
||||
for item in users:
|
||||
for item in aggregate:
|
||||
if not isinstance(item, dict):
|
||||
aggregate.append({'name': item})
|
||||
elif 'name' not in item:
|
||||
module.fail_json(msg='name is required')
|
||||
else:
|
||||
aggregate.append(item)
|
||||
|
||||
|
@ -278,8 +269,7 @@ def update_objects(want, have):
|
|||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
users=dict(type='list', aliases=['aggregate']),
|
||||
element_spec = dict(
|
||||
name=dict(),
|
||||
|
||||
full_name=dict(),
|
||||
|
@ -292,9 +282,20 @@ def main():
|
|||
state=dict(default='present', choices=['present', 'absent'])
|
||||
)
|
||||
|
||||
argument_spec.update(vyos_argument_spec)
|
||||
mutually_exclusive = [('name', 'users')]
|
||||
aggregate_spec = deepcopy(element_spec)
|
||||
aggregate_spec['name'] = 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, aliases=['users']),
|
||||
)
|
||||
|
||||
argument_spec.update(element_spec)
|
||||
argument_spec.update(vyos_argument_spec)
|
||||
|
||||
mutually_exclusive = [('name', 'aggregate')]
|
||||
module = AnsibleModule(argument_spec=argument_spec,
|
||||
mutually_exclusive=mutually_exclusive,
|
||||
supports_check_mode=True)
|
||||
|
|
|
@ -138,8 +138,9 @@
|
|||
- name: Disable interface on aggregate
|
||||
net_interface:
|
||||
aggregate:
|
||||
- { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, enabled: False}
|
||||
- { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, enabled: False}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
enabled: False
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
@ -151,8 +152,9 @@
|
|||
- name: Enable interface on aggregate
|
||||
net_interface:
|
||||
aggregate:
|
||||
- { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, enabled: True}
|
||||
- { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, enabled: True}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
enabled: True
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
@ -164,8 +166,9 @@
|
|||
- name: Delete interface aggregate
|
||||
net_interface:
|
||||
aggregate:
|
||||
- { name: eth1, state: absent}
|
||||
- { name: eth2, state: absent}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
@ -177,8 +180,9 @@
|
|||
- name: Delete interface aggregate (idempotent)
|
||||
net_interface:
|
||||
aggregate:
|
||||
- { name: eth1, state: absent}
|
||||
- { name: eth2, state: absent}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
|
|
@ -167,8 +167,9 @@
|
|||
- name: Disable interface on aggregate
|
||||
vyos_interface:
|
||||
aggregate:
|
||||
- { name: eth1, description: test-interface-1, enabled: False}
|
||||
- { name: eth2, description: test-interface-2, enabled: False}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
enabled: False
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
@ -180,8 +181,9 @@
|
|||
- name: Enable interface on aggregate
|
||||
vyos_interface:
|
||||
aggregate:
|
||||
- { name: eth1, description: test-interface-1, enabled: True}
|
||||
- { name: eth2, description: test-interface-2, enabled: True}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
enabled: True
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
@ -193,8 +195,9 @@
|
|||
- name: Delete interface aggregate
|
||||
vyos_interface:
|
||||
aggregate:
|
||||
- { name: eth1, state: absent}
|
||||
- { name: eth2, state: absent}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
@ -206,8 +209,9 @@
|
|||
- name: Delete interface aggregate (idempotent)
|
||||
vyos_interface:
|
||||
aggregate:
|
||||
- { name: eth1, state: absent}
|
||||
- { name: eth2, state: absent}
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
|
|
|
@ -156,8 +156,8 @@
|
|||
- name: Remove collection of linkagg definitions
|
||||
vyos_linkagg:
|
||||
aggregate:
|
||||
- { name: bond0 }
|
||||
- { name: bond1 }
|
||||
- name: bond0
|
||||
- name: bond1
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
|
@ -172,8 +172,8 @@
|
|||
- name: Remove collection of linkagg definitions again (idempotent)
|
||||
vyos_linkagg:
|
||||
aggregate:
|
||||
- { name: bond0 }
|
||||
- { name: bond1 }
|
||||
- name: bond0
|
||||
- name: bond1
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
|
|
|
@ -90,8 +90,8 @@
|
|||
- name: Create aggregate of LLDP interface configurations
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- { name: eth1 }
|
||||
- { name: eth2 }
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: present
|
||||
register: result
|
||||
|
||||
|
@ -104,8 +104,8 @@
|
|||
- name: Create aggregate of LLDP interface configurations again (idempotent)
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- { name: eth1 }
|
||||
- { name: eth2 }
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: present
|
||||
register: result
|
||||
|
||||
|
@ -116,7 +116,7 @@
|
|||
- name: Override LLDP interface configuration on aggregate
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- { name: eth1 }
|
||||
- name: eth1
|
||||
- { name: eth2, state: disabled }
|
||||
state: present
|
||||
register: result
|
||||
|
@ -129,7 +129,7 @@
|
|||
- name: Override LLDP interface configuration on aggregate again (idempotent)
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- { name: eth1 }
|
||||
- name: eth1
|
||||
- { name: eth2, state: disabled }
|
||||
state: present
|
||||
register: result
|
||||
|
@ -141,8 +141,8 @@
|
|||
- name: Delete aggregate of LLDP interface configurations
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- { name: eth1 }
|
||||
- { name: eth2 }
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
|
@ -155,8 +155,8 @@
|
|||
- name: Delete aggregate of LLDP interface configurations (idempotent)
|
||||
vyos_lldp_interface:
|
||||
aggregate:
|
||||
- { name: eth1 }
|
||||
- { name: eth2 }
|
||||
- name: eth1
|
||||
- name: eth2
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
|
|
Loading…
Reference in a new issue