1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Remove Deprecated Template network modules (#27076)

* removed deprecated networking template modules

* update changelog

* update changelog
This commit is contained in:
David Newswanger 2017-07-27 14:40:11 -04:00 committed by John R Barker
parent 0fb64214a4
commit 81151ef02c
86 changed files with 8 additions and 3420 deletions

View file

@ -50,6 +50,14 @@ Ansible Changes By Release
#### Deprecated Modules: #### Deprecated Modules:
* ec2_facts (removed in 2.7), replaced by ec2_metadata_facts * ec2_facts (removed in 2.7), replaced by ec2_metadata_facts
#### Removed Deprecated Modules:
* eos_template (use eos_config instead)
* ios_template (use ios_config instead)
* iosxr_template (use iosxr_config instead)
* junos_template (use junos_config instead)
* nxos_template (use nxos_config instead)
* ops_template (use ops_template instead)
### Minor Changes ### Minor Changes
* removed previously deprecated config option `hostfile` and env var `ANSIBLE_HOSTS` * removed previously deprecated config option `hostfile` and env var `ANSIBLE_HOSTS`
* removed unused and deprecated config option `pattern` * removed unused and deprecated config option `pattern`

View file

@ -1,232 +0,0 @@
#!/usr/bin/python
#
# 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/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: eos_template
version_added: "2.1"
author: "Peter Sprygada (@privateip)"
short_description: Manage Arista EOS device configurations
description:
- Manages network device configurations over SSH or eos_local. This module
allows implementers to work with the device running-config. It
provides a way to push a set of commands onto a network device
by evaluating the current running-config and only pushing configuration
commands that are not already configured. The config source can
be a set of commands or a template.
extends_documentation_fragment: eos
deprecated: Deprecated in 2.2. Use M(eos_config) instead
options:
src:
description:
- The path to the config source. The source can be either a
file with config or a template that will be merged during
runtime. By default the task will search for the source
file in role or playbook root folder in templates directory.
required: true
force:
description:
- The force argument instructs the module to not consider the
current devices running-config. When set to true, this will
cause the module to push the contents of I(src) into the device
without first checking if already configured.
required: false
default: false
choices: ['yes', 'no']
include_defaults:
description:
- By default when the M(eos_template) connects to the remote
device to retrieve the configuration it will issue the C(show
running-config) command. If this option is set to True then
the issued command will be C(show running-config all).
required: false
default: false
choices: ['yes', 'no']
backup:
description:
- When this argument is configured true, the module will backup
the running-config from the node prior to making any changes.
The backup file will be written to backup_{{ hostname }} in
the root of the playbook directory.
required: false
default: false
choices: ['yes', 'no']
replace:
description:
- This argument will cause the provided configuration to be replaced
on the destination node. The use of the replace argument will
always cause the task to set changed to true and will implies
C(force=true). This argument is only valid with C(transport=eos_local).
required: false
default: false
choices: ['yes', 'no']
config:
description:
- The module, by default, will connect to the remote device and
retrieve the current running-config to use as a base for comparing
against the contents of source. There are times when it is not
desirable to have the task get the current running-config for
every task in a playbook. The I(config) argument allows the
implementer to pass in the configuration to use as the base
config for comparison.
required: false
default: null
"""
EXAMPLES = """
- name: Push a configuration onto the device
eos_template:
src: config.j2
- name: Forceable push a configuration onto the device
eos_template:
src: config.j2
force: yes
- name: Provide the base configuration for comparison
eos_template:
src: candidate_config.txt
config: current_config.txt
"""
RETURN = """
updates:
description: The set of commands that will be pushed to the remote device
returned: always
type: list
sample: ['...', '...']
responses:
description: The set of responses from issuing the commands on the device
returned: when not check_mode
type: list
sample: ['...', '...']
"""
import re
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.eos import load_config, get_config
from ansible.module_utils.eos import eos_argument_spec
from ansible.module_utils.eos import check_args as eos_check_args
from ansible.module_utils.netcfg import NetworkConfig, dumps
def check_args(module, warnings):
eos_check_args(module, warnings)
transport = module.params['transport']
provider_transport = (module.params['provider'] or {}).get('transport')
if module.params['replace'] and 'eapi' in (transport, provider_transport):
module.fail_json(msg='config replace is only supported over cli')
def get_current_config(module):
config = module.params.get('config')
if not config and not module.params['force']:
flags = []
if module.params['include_defaults']:
flags.append('all')
config = get_config(module, flags)
return config
def filter_exit(commands):
# Filter out configuration mode commands followed immediately by an
# exit command indented by one level only, e.g.
# - route-map map01 permit 10
# - exit
#
# Build a temporary list as we filter, then copy the temp list
# back onto the commands list.
temp = []
ind_prev = 999
count = 0
for c in commands:
ind_this = c.count(' ')
if re.search(r"^\s*exit$", c) and ind_this == ind_prev + 1:
temp.pop()
count -= 1
if count != 0:
ind_prev = temp[-1].count(' ')
continue
temp.append(c)
ind_prev = ind_this
count += 1
return temp
def main():
""" main entry point for module execution
"""
argument_spec = dict(
src=dict(required=True),
force=dict(default=False, type='bool'),
include_defaults=dict(default=False, type='bool'),
backup=dict(default=False, type='bool'),
replace=dict(default=False, type='bool'),
config=dict()
)
argument_spec.update(eos_argument_spec)
mutually_exclusive = [('config', 'backup'), ('config', 'force')]
module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
warnings = list()
check_args(module, warnings)
result = {'changed': False}
if warnings:
result['warnings'] = warnings
src = module.params['src']
candidate = NetworkConfig(contents=src, indent=3)
if module.params['backup']:
result['__backup__'] = get_config(module)
if not module.params['force']:
contents = get_current_config(module)
configobj = NetworkConfig(contents=contents, indent=3)
commands = candidate.difference(configobj)
commands = dumps(commands, 'commands').split('\n')
commands = [str(c).strip() for c in commands if c]
else:
commands = [c.strip() for c in str(candidate).split('\n')]
#commands = str(candidate).split('\n')
if commands:
commands = filter_exit(commands)
commit = not module.check_mode
replace = module.params['replace'] or False
load_config(module, commands, commit=commit, replace=replace)
result['changed'] = True
result['commands'] = commands
result['updates'] = commands
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,175 +0,0 @@
#!/usr/bin/python
#
# 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/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: ios_template
version_added: "2.1"
author: "Peter Sprygada (@privateip)"
short_description: Manage Cisco IOS device configurations over SSH
description:
- Manages Cisco IOS network device configurations over SSH. This module
allows implementers to work with the device running-config. It
provides a way to push a set of commands onto a network device
by evaluating the current running-config and only pushing configuration
commands that are not already configured. The config source can
be a set of commands or a template.
deprecated: Deprecated in 2.2. Use M(ios_config) instead.
extends_documentation_fragment: ios
options:
src:
description:
- The path to the config source. The source can be either a
file with config or a template that will be merged during
runtime. By default the task will first search for the source
file in role or playbook root folder in templates unless a full
path to the file is given.
required: true
force:
description:
- The force argument instructs the module not to consider the
current device running-config. When set to true, this will
cause the module to push the contents of I(src) into the device
without first checking if already configured.
required: false
default: false
choices: [ "true", "false" ]
include_defaults:
description:
- The module, by default, will collect the current device
running-config to use as a base for comparison to the commands
in I(src). Setting this value to true will cause the command
issued to add any necessary flags to collect all defaults as
well as the device configuration. If the destination device
does not support such a flag, this argument is silently ignored.
required: true
choices: [ "true", "false" ]
backup:
description:
- When this argument is configured true, the module will backup
the running-config from the node prior to making any changes.
The backup file will be written to backup_{{ hostname }} in
the root of the playbook directory.
required: false
default: false
choices: [ "true", "false" ]
config:
description:
- The module, by default, will connect to the remote device and
retrieve the current running-config to use as a base for comparing
against the contents of source. There are times when it is not
desirable to have the task get the current running-config for
every task. The I(config) argument allows the implementer to
pass in the configuration to use as the base config for
comparison.
required: false
default: null
"""
EXAMPLES = """
- name: push a configuration onto the device
ios_template:
src: config.j2
- name: forceable push a configuration onto the device
ios_template:
src: config.j2
force: yes
- name: provide the base configuration for comparison
ios_template:
src: candidate_config.txt
config: current_config.txt
"""
RETURN = """
updates:
description: The set of commands that will be pushed to the remote device
returned: always
type: list
sample: ['...', '...']
"""
from ansible.module_utils.ios import load_config, get_config
from ansible.module_utils.ios import ios_argument_spec, check_args
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.netcli import Conditional
from ansible.module_utils.netcfg import NetworkConfig, dumps
def get_current_config(module):
if module.params['config']:
return module.params['config']
if module.params['include_defaults']:
flags = ['all']
else:
flags = []
return get_config(module=module, flags=flags)
def main():
""" main entry point for module execution
"""
argument_spec = dict(
src=dict(),
force=dict(default=False, type='bool'),
include_defaults=dict(default=True, type='bool'),
backup=dict(default=False, type='bool'),
config=dict(),
)
argument_spec.update(ios_argument_spec)
mutually_exclusive = [('config', 'backup'), ('config', 'force')]
module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
candidate = NetworkConfig(contents=module.params['src'], indent=1)
result = {'changed': False}
warnings = list()
check_args(module, warnings)
result['warnings'] = warnings
if module.params['backup']:
result['__backup__'] = get_config(module=module)
if not module.params['force']:
contents = get_current_config(module)
configobj = NetworkConfig(contents=contents, indent=1)
commands = candidate.difference(configobj)
commands = dumps(commands, 'commands').split('\n')
commands = [str(c).strip() for c in commands if c]
else:
commands = [c.strip() for c in str(candidate).split('\n')]
if commands:
if not module.check_mode:
load_config(module, commands)
result['changed'] = True
result['updates'] = commands
result['commands'] = commands
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,158 +0,0 @@
#!/usr/bin/python
#
# 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/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: iosxr_template
version_added: "2.1"
author: "Ricardo Carrillo Cruz (@rcarrillocruz)"
short_description: Manage Cisco IOS XR device configurations over SSH
description:
- Manages network device configurations over SSH. This module
allows implementers to work with the device running-config. It
provides a way to push a set of commands onto a network device
by evaluating the current running-config and only pushing configuration
commands that are not already configured. The config source can
be a set of commands or a template.
deprecated: Deprecated in 2.2. Use M(iosxr_config) instead.
extends_documentation_fragment: iosxr
options:
src:
description:
- The path to the config source. The source can be either a
file with config or a template that will be merged during
runtime. By default the task will first search for the source
file in role or playbook root folder in templates unless a full
path to the file is given.
required: false
default: null
force:
description:
- The force argument instructs the module not to consider the
current device running-config. When set to true, this will
cause the module to push the contents of I(src) into the device
without first checking if already configured.
required: false
default: false
choices: [ "true", "false" ]
backup:
description:
- When this argument is configured true, the module will backup
the running-config from the node prior to making any changes.
The backup file will be written to backup_{{ hostname }} in
the root of the playbook directory.
required: false
default: false
choices: [ "true", "false" ]
config:
description:
- The module, by default, will connect to the remote device and
retrieve the current running-config to use as a base for comparing
against the contents of source. There are times when it is not
desirable to have the task get the current running-config for
every task. The I(config) argument allows the implementer to
pass in the configuration to use as the base config for
comparison.
required: false
default: null
"""
EXAMPLES = """
- name: push a configuration onto the device
iosxr_template:
src: config.j2
- name: forceable push a configuration onto the device
iosxr_template:
src: config.j2
force: yes
- name: provide the base configuration for comparison
iosxr_template:
src: candidate_config.txt
config: current_config.txt
"""
RETURN = """
updates:
description: The set of commands that will be pushed to the remote device
returned: always
type: list
sample: ['...', '...']
"""
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.netcfg import NetworkConfig, dumps
from ansible.module_utils.iosxr import get_config, load_config
from ansible.module_utils.iosxr import iosxr_argument_spec, check_args
def main():
""" main entry point for module execution
"""
argument_spec = dict(
src=dict(),
force=dict(default=False, type='bool'),
backup=dict(default=False, type='bool'),
config=dict(),
)
argument_spec.update(iosxr_argument_spec)
mutually_exclusive = [('config', 'backup'), ('config', 'force')]
module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
warnings = list()
check_args(module, warnings)
result = dict(changed=False, warnings=warnings)
candidate = NetworkConfig(contents=module.params['src'], indent=1)
if module.params['backup']:
result['__backup__'] = get_config(module)
if not module.params['force']:
contents = get_config(module)
configobj = NetworkConfig(contents=contents, indent=1)
commands = candidate.difference(configobj)
commands = dumps(commands, 'commands').split('\n')
commands = [str(c).strip() for c in commands if c]
else:
commands = [c.strip() for c in str(candidate).split('\n')]
if commands:
load_config(module, commands, result['warnings'], not module.check_mode)
result['changed'] = not module.check_mode
result['updates'] = commands
result['commands'] = commands
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,173 +0,0 @@
#!/usr/bin/python
#
# 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/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: junos_template
version_added: "2.1"
author: "Peter Sprygada (@privateip)"
short_description: Manage configuration on remote devices running Juniper JUNOS
description:
- This module will load a candidate configuration
from a template file onto a remote device running Junos. The
module will return the differences in configuration if the diff
option is specified on the Ansible command line
deprecated: Deprecated in 2.2. Use M(junos_config) instead.
extends_documentation_fragment: junos
options:
src:
description:
- The path to the config source. The source can be either a
file with config or a template that will be merged during
runtime. By default the task will search for the source
file in role or playbook root folder in templates directory.
required: true
default: null
backup:
description:
- When this argument is configured true, the module will backup
the configuration from the node prior to making any changes.
The backup file will be written to backup_{{ hostname }} in
the root of the playbook directory.
required: false
default: false
choices: ["true", "false"]
confirm:
description:
- The C(confirm) argument will configure a time out value for
the commit to be confirmed before it is automatically
rolled back. If the C(confirm) argument is set to False, this
argument is silently ignored. If the value for this argument
is set to 0, the commit is confirmed immediately.
required: false
default: 0
comment:
description:
- The C(comment) argument specifies a text string to be used
when committing the configuration. If the C(confirm) argument
is set to False, this argument is silently ignored.
required: false
default: configured by junos_template
action:
description:
- The C(action) argument specifies how the module will apply changes.
required: false
default: merge
choices: ['merge', 'overwrite', 'replace']
version_added: "2.2"
config_format:
description:
- The C(format) argument specifies the format of the configuration
template specified in C(src). If the format argument is not
specified, the module will attempt to infer the configuration
format based of file extension. Files that end in I(xml) will set
the format to xml. Files that end in I(set) will set the format
to set and all other files will default the format to text.
required: false
default: null
choices: ['text', 'xml', 'set']
requirements:
- ncclient (>=v0.5.2)
notes:
- This module requires the netconf system service be enabled on
the remote device being managed
"""
EXAMPLES = """
- junos_template:
src: config.j2
comment: update system config
- name: replace config hierarchy
junos_template:
src: config.j2
action: replace
- name: overwrite the config
junos_template:
src: config.j2
action: overwrite
"""
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.junos import check_args, junos_argument_spec
from ansible.module_utils.junos import get_configuration, load_config
from ansible.module_utils.junos import commit_configuration, discard_changes, locked_config
USE_PERSISTENT_CONNECTION = True
DEFAULT_COMMENT = 'configured by junos_template'
def main():
argument_spec = dict(
src=dict(required=True, type='path'),
confirm=dict(default=0, type='int'),
comment=dict(default=DEFAULT_COMMENT),
action=dict(default='merge', choices=['merge', 'overwrite', 'replace']),
config_format=dict(choices=['text', 'set', 'xml'], default='text'),
backup=dict(default=False, type='bool'),
)
argument_spec.update(junos_argument_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
warnings = list()
check_args(module, warnings)
result = {'changed': False, 'warnings': warnings}
commit = not module.check_mode
action = module.params['action']
src = module.params['src']
fmt = module.params['config_format']
if action == 'overwrite' and fmt == 'set':
module.fail_json(msg="overwrite cannot be used when format is set per junos-pyez documentation")
if module.params['backup']:
reply = get_configuration(module, format='set')
match = reply.find('.//configuration-set')
if match is None:
module.fail_json(msg='unable to retrieve device configuration')
result['__backup__'] = str(match.text).strip()
with locked_config(module):
diff = load_config(module, src, warnings, action=action, format=fmt)
if diff:
if commit:
commit_configuration(module)
else:
discard_changes(module)
result['changed'] = True
if module._diff:
result['diff'] = {'prepared': diff}
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,178 +0,0 @@
#!/usr/bin/python
#
# 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/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: nxos_template
version_added: "2.1"
author: "Peter Sprygada (@privateip)"
short_description: Manage Cisco NXOS device configurations
description:
- Manages network device configurations over SSH or NXAPI. This module
allows implementers to work with the device running-config. It
provides a way to push a set of commands onto a network device
by evaluating the current running-config and only pushing configuration
commands that are not already configured. The config source can
be a set of commands or a template.
deprecated: Deprecated in 2.2. Use M(nxos_config) instead.
options:
src:
description:
- The path to the config source. The source can be either a
file with config or a template that will be merged during
runtime. By default the task will search for the source
file in role or playbook root folder in templates directory.
required: false
default: null
force:
description:
- The force argument instructs the module to not consider the
current devices running-config. When set to true, this will
cause the module to push the contents of I(src) into the device
without first checking if already configured.
required: false
default: false
choices: [ "true", "false" ]
include_defaults:
description:
- The module, by default, will collect the current device
running-config to use as a base for comparisons to the commands
in I(src). Setting this value to true will cause the module
to issue the command C(show running-config all) to include all
device settings.
required: false
default: false
choices: [ "true", "false" ]
backup:
description:
- When this argument is configured true, the module will backup
the running-config from the node prior to making any changes.
The backup file will be written to backup_{{ hostname }} in
the root of the playbook directory.
required: false
default: false
choices: [ "true", "false" ]
config:
description:
- The module, by default, will connect to the remote device and
retrieve the current running-config to use as a base for comparing
against the contents of source. There are times when it is not
desirable to have the task get the current running-config for
every task in a playbook. The I(config) argument allows the
implementer to pass in the configuration to use as the base
config for comparison.
required: false
default: null
"""
EXAMPLES = """
- name: push a configuration onto the device
nxos_template:
src: config.j2
- name: forceable push a configuration onto the device
nxos_template:
src: config.j2
force: yes
- name: provide the base configuration for comparison
nxos_template:
src: candidate_config.txt
config: current_config.txt
"""
RETURN = """
updates:
description: The set of commands that will be pushed to the remote device
returned: always
type: list
sample: ['...', '...']
responses:
description: The set of responses from issuing the commands on the device
returned: when not check_mode
type: list
sample: ['...', '...']
"""
from ansible.module_utils.nxos import load_config, get_config
from ansible.module_utils.nxos import nxos_argument_spec
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.netcfg import NetworkConfig, dumps
def get_current_config(module):
config = module.params.get('config')
if not config and not module.params['force']:
flags = []
if module.params['include_defaults']:
flags.append('all')
config = get_config(module, flags)
return config
def main():
""" main entry point for module execution
"""
argument_spec = dict(
src=dict(),
force=dict(default=False, type='bool'),
include_defaults=dict(default=True, type='bool'),
backup=dict(default=False, type='bool'),
config=dict(),
)
argument_spec.update(nxos_argument_spec)
mutually_exclusive = [('config', 'backup'), ('config', 'force')]
module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
result = dict(changed=False)
candidate = NetworkConfig(contents=module.params['src'], indent=2)
contents = get_current_config(module)
if contents:
config = NetworkConfig(contents=contents, indent=2)
result['__backup__'] = str(contents)
if not module.params['force']:
commands = candidate.difference(config)
commands = dumps(commands, 'commands').split('\n')
commands = [str(c) for c in commands if c]
else:
commands = str(candidate).split('\n')
if commands:
if not module.check_mode:
load_config(module, commands)
result['changed'] = True
result['updates'] = commands
result['commands'] = commands
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,227 +0,0 @@
#!/usr/bin/python
#
# 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/>.
#
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['deprecated'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: ops_template
version_added: "2.1"
author: "Peter Sprygada (@privateip)"
short_description: Push configuration to OpenSwitch
description:
- The OpenSwitch platform provides a library for pushing JSON structured
configuration files into the current running-config. This module
will read the current configuration from OpenSwitch and compare it
against a provided candidate configuration. If there are changes, the
candidate configuration is merged with the current configuration and
pushed into OpenSwitch
deprecated: Deprecated in 2.2. Use M(ops_config) instead.
extends_documentation_fragment: openswitch
options:
src:
description:
- The path to the config source. The source can be either a
file with config or a template that will be merged during
runtime. By default the task will search for the source
file in role or playbook root folder in templates directory.
required: true
force:
description:
- The force argument instructs the module to not consider the
current devices running-config. When set to true, this will
cause the module to push the contents of I(src) into the device
without first checking if already configured.
required: false
default: false
choices: ['yes', 'no']
backup:
description:
- When this argument is configured true, the module will backup
the running-config from the node prior to making any changes.
The backup file will be written to backups/ in
the root of the playbook directory.
required: false
default: false
choices: ['yes', 'no']
config:
description:
- The module, by default, will connect to the remote device and
retrieve the current running-config to use as a base for comparing
against the contents of source. There are times when it is not
desirable to have the task get the current running-config for
every task in a playbook. The I(config) argument allows the
implementer to pass in the configuration to use as the base
config for comparison.
required: false
default: null
"""
EXAMPLES = """
- name: set hostname with file lookup
ops_template:
src: ./hostname.json
backup: yes
remote_user: admin
become: yes
- name: set hostname with var
ops_template:
src: "{{ config }}"
remote_user: admin
become: yes
"""
RETURN = """
updates:
description: The list of configuration updates to be merged
returned: always
type: dict
sample: {obj, obj}
responses:
description: returns the responses when configuring using cli
returned: when transport == cli
type: list
sample: [...]
"""
import ansible.module_utils.openswitch
from ansible.module_utils.netcfg import NetworkConfig, dumps
from ansible.module_utils.network import NetworkModule
from ansible.module_utils.openswitch import HAS_OPS
def get_config(module):
config = module.params['config'] or dict()
if not config and not module.params['force']:
config = module.config.get_config()
return config
def sort(val):
if isinstance(val, (list, set)):
return sorted(val)
return val
def diff(this, other, path=None):
updates = list()
path = path or list()
for key, value in this.items():
if key not in other:
other_value = other.get(key)
updates.append((list(path), key, value, other_value))
else:
if isinstance(this[key], dict):
path.append(key)
updates.extend(diff(this[key], other[key], list(path)))
path.pop()
else:
other_value = other.get(key)
if sort(this[key]) != sort(other_value):
updates.append((list(path), key, value, other_value))
return updates
def merge(changeset, config=None):
config = config or dict()
for path, key, value, _ in changeset:
current_level = config
for part in path:
if part not in current_level:
current_level[part] = dict()
current_level = current_level[part]
current_level[key] = value
return config
def main():
""" main entry point for module execution
"""
argument_spec = dict(
src=dict(type='str'),
force=dict(default=False, type='bool'),
backup=dict(default=False, type='bool'),
config=dict(type='dict'),
)
mutually_exclusive = [('config', 'backup'), ('config', 'force')]
module = NetworkModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
if not module.params['transport'] and not HAS_OPS:
module.fail_json(msg='unable to import ops.dc library')
result = dict(changed=False)
contents = get_config(module)
result['_backup'] = contents
if module.params['transport'] in ['ssh', 'rest']:
config = contents
try:
src = module.from_json(module.params['src'])
except ValueError:
module.fail_json(msg='unable to load src due to json parsing error')
changeset = diff(src, config)
candidate = merge(changeset, config)
updates = dict()
for path, key, new_value, old_value in changeset:
path = '%s.%s' % ('.'.join(path), key)
updates[path] = str(new_value)
result['updates'] = updates
if changeset:
if not module.check_mode:
module.config(config)
result['changed'] = True
else:
candidate = NetworkConfig(contents=module.params['src'], indent=4)
if contents:
config = NetworkConfig(contents=contents, indent=4)
if not module.params['force']:
commands = candidate.difference(config)
commands = dumps(commands, 'commands').split('\n')
commands = [str(c) for c in commands if c]
else:
commands = str(candidate).split('\n')
if commands:
if not module.check_mode:
response = module.config(commands)
result['responses'] = response
result['changed'] = True
result['updates'] = commands
module.exit_json(**result)
if __name__ == '__main__':
main()

View file

@ -1,103 +0,0 @@
#
# Copyright 2015 Peter Sprygada <psprygada@ansible.com>
#
# 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
import os
import time
import glob
import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.eos import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
try:
self._handle_template()
except (ValueError, AttributeError) as exc:
return dict(failed=True, msg=exc.message)
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, __backup__ key may not be in results.
self._write_backup(task_vars['inventory_hostname'], result['__backup__'])
if '__backup__' in result:
del result['__backup__']
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
def _handle_template(self):
src = self._task.args.get('src')
if not src:
raise ValueError('missing required arguments: src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlparse.urlsplit(src).scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
return
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -1,103 +0,0 @@
#
# Copyright 2015 Peter Sprygada <psprygada@ansible.com>
#
# 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
import os
import time
import glob
import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.ios import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
try:
self._handle_template()
except (ValueError, AttributeError) as exc:
return dict(failed=True, msg=exc.message)
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, __backup__ key may not be in results.
self._write_backup(task_vars['inventory_hostname'], result['__backup__'])
if '__backup__' in result:
del result['__backup__']
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
def _handle_template(self):
src = self._task.args.get('src')
if not src:
raise ValueError('missing required arguments: src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlparse.urlsplit(src).scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
return
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -1,103 +0,0 @@
#
# Copyright 2015 Peter Sprygada <psprygada@ansible.com>
#
# 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
import os
import time
import glob
import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.iosxr import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
try:
self._handle_template()
except (ValueError, AttributeError) as exc:
return dict(failed=True, msg=exc.message)
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, __backup__ key may not be in results.
self._write_backup(task_vars['inventory_hostname'], result['__backup__'])
if '__backup__' in result:
del result['__backup__']
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
def _handle_template(self):
src = self._task.args.get('src')
if not src:
raise ValueError('missing required arguments: src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlparse.urlsplit(src).scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
return
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -1,118 +0,0 @@
#
# (c) 2017 Red Hat, 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
import os
import time
import glob
import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.junos import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
src = self._task.args.get('src')
if self._task.args.get('config_format') is None:
if src.endswith('.xml'):
fmt = 'xml'
elif src.endswith('.set'):
fmt = 'set'
else:
fmt = 'text'
self._task.args['config_format'] = fmt
if self._task.args.get('comment') is None:
self._task.args['comment'] = self._task.name
try:
self._handle_template()
except (ValueError, AttributeError) as exc:
return dict(failed=True, msg=exc.message)
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, __backup__ key may not be in results.
self._write_backup(task_vars['inventory_hostname'], result['__backup__'])
if '__backup__' in result:
del result['__backup__']
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
def _handle_template(self):
src = self._task.args.get('src')
if not src:
raise ValueError('missing required arguments: src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlparse.urlsplit(src).scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
return
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -1,103 +0,0 @@
#
# (c) 2016 Red Hat 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
import os
import time
import glob
import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.normal import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
try:
self._handle_template()
except (ValueError, AttributeError) as exc:
return dict(failed=True, msg=exc.message)
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, __backup__ key may not be in results.
self._write_backup(task_vars['inventory_hostname'], result['__backup__'])
if '__backup__' in result:
del result['__backup__']
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
def _handle_template(self):
src = self._task.args.get('src')
if not src:
raise ValueError('missing required arguments: src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlparse.urlsplit(src).scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
return
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -1,103 +0,0 @@
#
# Copyright 2015 Peter Sprygada <psprygada@ansible.com>
#
# 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
import os
import time
import glob
from ansible.module_utils._text import to_text
from ansible.module_utils.six.moves.urllib.parse import urlsplit
from ansible.plugins.action.nxos import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
try:
self._handle_template()
except (ValueError, AttributeError) as exc:
return dict(failed=True, msg=str(exc))
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, __backup__ key may not be in results.
self._write_backup(task_vars['inventory_hostname'], result['__backup__'])
if '__backup__' in result:
del result['__backup__']
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
def _handle_template(self):
src = self._task.args.get('src')
if not src:
raise ValueError('missing required arguments: src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlsplit(src).scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
return
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -1,50 +0,0 @@
#
# Copyright 2015 Peter Sprygada <psprygada@ansible.com>
#
# 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
import json
from ansible.module_utils.six import string_types
from ansible.plugins.action import ActionBase
from ansible.plugins.action.net_template import ActionModule as NetActionModule
class ActionModule(NetActionModule, ActionBase):
def run(self, tmp=None, task_vars=None):
if self._connection.transport == 'local':
return super(ActionModule, self).run(tmp, task_vars)
result = dict(changed=False)
if isinstance(self._task.args['src'], string_types):
self._handle_template()
result.update(self._execute_module(module_name=self._task.action,
module_args=self._task.args, task_vars=task_vars))
if self._task.args.get('backup') and result.get('_backup'):
contents = json.dumps(result['_backup'], indent=4)
self._write_backup(task_vars['inventory_hostname'], contents)
if '_backup' in result:
del result['_backup']
return result

View file

@ -40,15 +40,6 @@
failed_modules: "{{ failed_modules }} + [ 'eos_config' ]" failed_modules: "{{ failed_modules }} + [ 'eos_config' ]"
test_failed: true test_failed: true
- block:
- include_role:
name: eos_template
when: "limit_to in ['*', 'eos_template']"
rescue:
- set_fact:
failed_modules: "{{ failed_modules }} + [ 'eos_template' ]"
test_failed: true
- block: - block:
- include_role: - include_role:
name: eos_facts name: eos_facts

View file

@ -49,15 +49,6 @@
failed_modules: "{{ failed_modules }} + [ 'ios_facts' ]" failed_modules: "{{ failed_modules }} + [ 'ios_facts' ]"
test_failed: true test_failed: true
- block:
- include_role:
name: ios_template
when: "limit_to in ['*', 'ios_template']"
rescue:
- set_fact:
failed_modules: "{{ failed_modules }} + [ 'ios_template' ]"
test_failed: true
- block: - block:
- include_role: - include_role:
name: ios_system name: ios_system

View file

@ -42,15 +42,6 @@
failed_modules: "{{ failed_modules }} + [ 'iosxr_facts' ]" failed_modules: "{{ failed_modules }} + [ 'iosxr_facts' ]"
test_failed: true test_failed: true
- block:
- include_role:
name: iosxr_template
when: "limit_to in ['*', 'iosxr_template']"
rescue:
- set_fact:
failed_modules: "{{ failed_modules }} + [ 'iosxr_template' ]"
test_failed: true
- block: - block:
- include_role: - include_role:
name: iosxr_system name: iosxr_system

View file

@ -61,14 +61,6 @@
failed_modules: "{{ failed_modules }} + [ 'junos_rpc' ]" failed_modules: "{{ failed_modules }} + [ 'junos_rpc' ]"
test_failed: true test_failed: true
- block:
- include_role:
name: junos_template
when: "limit_to in ['*', 'junos_template']"
rescue:
- set_fact:
failed_modules: "{{ failed_modules }} + [ 'junos_template' ]"
test_failed: true
- block: - block:
- include_role: - include_role:
name: junos_vlan name: junos_vlan

View file

@ -42,15 +42,6 @@
failed_modules: "{{ failed_modules }} + [ 'nxos_facts' ]" failed_modules: "{{ failed_modules }} + [ 'nxos_facts' ]"
test_failed: true test_failed: true
- block:
- include_role:
name: nxos_template
when: "limit_to in ['*', 'nxos_template']"
rescue:
- set_fact:
failed_modules: "{{ failed_modules }} + [ 'nxos_template' ]"
test_failed: true
- block: - block:
- include_role: - include_role:
name: nxos_nxapi name: nxos_nxapi

View file

@ -1,2 +0,0 @@
---
testcase: "*"

View file

@ -1,2 +0,0 @@
dependencies:
- prepare_eos_tests

View file

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

View file

@ -1,28 +0,0 @@
---
- name: collect all eapi test cases
find:
paths: "{{ role_path }}/tests/eapi"
patterns: "{{ testcase }}.yaml"
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: enable eapi
eos_eapi:
http: yes
https: yes
local_http: no
enable_socket: yes
provider: "{{ cli }}"
- name: run test case
include: "{{ test_case_to_run }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
- name: disable eapi
eos_eapi:
state: stopped
provider: "{{ cli }}"

View file

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

View file

@ -1,4 +0,0 @@
interface Ethernet2
description this is a test
shutdown

View file

@ -1,4 +0,0 @@
interface Ethernet2
description test description from ansible
shutdown

View file

@ -1,3 +0,0 @@
interface Ethernet2
description this is a test
no shutdown

View file

@ -1,4 +0,0 @@
interface Ethernet2
description this is a test
shutdown

View file

@ -1,50 +0,0 @@
---
- debug: msg="START cli/backup.yaml"
- name: setup
eos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ cli }}"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure device with config
eos_template:
src: basic/config.j2
backup: yes
provider: "{{ cli }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- debug: msg="END cli/backup.yaml"

View file

@ -1,36 +0,0 @@
---
- debug: msg="START cli/basic.yaml"
- name: setup
eos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ cli }}"
- name: configure device with config
eos_template:
src: basic/config.j2
provider: "{{ cli }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
eos_template:
src: basic/config.j2
provider: "{{ cli }}"
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END cli/basic.yaml"

View file

@ -1,42 +0,0 @@
---
- debug: msg="START cli/defaults.yaml"
- name: setup
eos_config:
commands:
- no description
- shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ cli }}"
- name: configure device with defaults included
eos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ cli }}"
register: result
- debug: var=result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with defaults included
eos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ cli }}"
register: result
- debug: var=result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END cli/defaults.yaml"

View file

@ -1,38 +0,0 @@
---
- debug: msg="START cli/force.yaml"
- name: setup
eos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ cli }}"
- name: configure device with config
eos_template:
src: basic/config.j2
provider: "{{ cli }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
eos_template:
src: basic/config.j2
provider: "{{ cli }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- debug: msg="END cli/force.yaml"

View file

@ -1,50 +0,0 @@
---
- debug: msg="START eapi/backup.yaml"
- name: setup
eos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ eapi }}"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure device with config
eos_template:
src: basic/config.j2
backup: yes
provider: "{{ eapi }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- debug: msg="END eapi/backup.yaml"

View file

@ -1,36 +0,0 @@
---
- debug: msg="START eapi/basic.yaml"
- name: setup
eos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ eapi }}"
- name: configure device with config
eos_template:
src: basic/config.j2
provider: "{{ eapi }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
eos_template:
src: basic/config.j2
provider: "{{ eapi }}"
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END eapi/basic.yaml"

View file

@ -1,42 +0,0 @@
---
- debug: msg="START eapi/defaults.yaml"
- name: setup
eos_config:
commands:
- no description
- shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ eapi }}"
- name: configure device with defaults included
eos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ eapi }}"
register: result
#- debug: var=result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with defaults included
eos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ eapi }}"
register: result
#- debug: var=result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END eapi/defaults.yaml"

View file

@ -1,38 +0,0 @@
---
- debug: msg="START eapi/force.yaml"
- name: setup
eos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2
match: none
provider: "{{ eapi }}"
- name: configure device with config
eos_template:
src: basic/config.j2
provider: "{{ eapi }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
eos_template:
src: basic/config.j2
provider: "{{ eapi }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- debug: msg="END eapi/force.yaml"

View file

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

View file

@ -1,2 +0,0 @@
dependencies:
- prepare_ios_tests

View file

@ -1,16 +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
include: "{{ test_case_to_run }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

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

View file

@ -1,4 +0,0 @@
interface Loopback999
description this is a test
shutdown

View file

@ -1,4 +0,0 @@
interface Loopback999
description this is a test
no shutdown

View file

@ -1,52 +0,0 @@
---
- debug: msg="START cli/backup.yaml"
- name: setup
ios_config:
commands:
- no interface Loopback999
match: none
ignore_errors: yes
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure device with config
ios_template:
src: basic/config.j2
backup: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- name: teardown
ios_config:
commands:
- no interface Loopback999
match: none
- debug: msg="END cli/backup.yaml"

View file

@ -1,37 +0,0 @@
---
- debug: msg="START cli/basic.yaml"
- name: setup
ios_config:
commands:
- no interface Loopback999
match: none
ignore_errors: yes
- name: configure device with config
ios_template:
src: basic/config.j2
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
ios_template:
src: basic/config.j2
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- name: teardown
ios_config:
commands:
- no interface Loopback999
match: none
- debug: msg="END cli/basic.yaml"

View file

@ -1,37 +0,0 @@
---
- debug: msg="START cli/defaults.yaml"
- name: setup
ios_config:
commands: no interface Loopback999
match: none
ignore_errors: yes
- name: configure device with defaults included
ios_template:
src: defaults/config.j2
include_defaults: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with defaults included
ios_template:
src: defaults/config.j2
include_defaults: yes
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- name: teardown
ios_config:
commands: no interface Loopback999
match: none
- debug: msg="END cli/defaults.yaml"

View file

@ -1,39 +0,0 @@
---
- debug: msg="START cli/force.yaml"
- name: setup
ios_config:
commands:
- no interface Loopback999
match: none
ignore_errors: yes
- name: configure device with config
ios_template:
src: basic/config.j2
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
ios_template:
src: basic/config.j2
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: teardown
ios_config:
commands:
- no interface Loopback999
match: none
- debug: msg="END cli/force.yaml"

View file

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

View file

@ -1,2 +0,0 @@
dependencies:
- prepare_iosxr_tests

View file

@ -1,16 +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
include: "{{ test_case_to_run }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

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

View file

@ -1,5 +0,0 @@
hostname {{ inventory_hostname_short }}
!
interface Loopback999
description this is a test
shutdown

View file

@ -1,52 +0,0 @@
---
- debug: msg="START cli/backup.yaml"
- name: setup
iosxr_config:
commands:
- no interface Loopback999
match: none
ignore_errors: yes
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure device with config
iosxr_template:
src: basic/config.j2
backup: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- name: teardown
iosxr_config:
commands:
- no interface Loopback999
match: none
- debug: msg="END cli/backup.yaml"

View file

@ -1,36 +0,0 @@
---
- debug: msg="START cli/basic.yaml"
- name: setup
iosxr_config:
commands:
- no interface Loopback999
match: none
- name: configure device with config
iosxr_template:
src: basic/config.j2
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
iosxr_template:
src: basic/config.j2
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- name: teardown
iosxr_config:
commands:
- no interface Loopback999
match: none
- debug: msg="END cli/basic.yaml"

View file

@ -1,38 +0,0 @@
---
- debug: msg="START cli/force.yaml"
- name: setup
iosxr_config:
commands:
- no interface Loopback999
match: none
- name: configure device with config
iosxr_template:
src: basic/config.j2
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
iosxr_template:
src: basic/config.j2
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: teardown
iosxr_config:
commands:
- no interface Loopback999
match: none
- debug: msg="END cli/force.yaml"

View file

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

View file

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

View file

@ -1,15 +0,0 @@
---
- name: collect netconf test cases
find:
paths: "{{ role_path }}/tests/netconf"
patterns: "{{ testcase }}.yaml"
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: run test case
include: "{{ test_case_to_run }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

@ -1,10 +0,0 @@
interfaces {
lo0 {
unit 0 {
family inet {
address 1.1.1.1/32;
}
}
}
}

View file

@ -1,54 +0,0 @@
---
- debug: msg="START netconf/backup.yaml"
- name: setup
junos_config:
lines:
- set system host-name {{ inventory_hostname_short }}
- delete interfaces lo0
provider: "{{ netconf }}"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure using template with backup
junos_template:
src: basic/config.j2
backup: yes
provider: "{{ netconf }}"
register: result
- assert:
that:
- "result.changed == true"
- "'1.1.1.1/32' in result.diff.prepared"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- name: teardown
junos_config:
lines:
- set system host-name {{ inventory_hostname_short }}
- delete interfaces lo0
provider: "{{ netconf }}"
- debug: msg="END netconf/backup.yaml"

View file

@ -1,39 +0,0 @@
---
- debug: msg="START netconf/basic.yaml"
- name: setup
junos_config:
lines:
- set system host-name {{ inventory_hostname_short }}
- delete interfaces lo0
provider: "{{ netconf }}"
- name: configure basic config template
junos_template:
src: basic/config.j2
provider: "{{ netconf }}"
register: result
- assert:
that:
- "result.changed == true"
- "'1.1.1.1/32' in result.diff.prepared"
- name: check basic config template idempotent
junos_template:
src: basic/config.j2
provider: "{{ netconf }}"
register: result
- assert:
that:
- "result.changed == false"
- name: teardown
junos_config:
lines:
- set system host-name {{ inventory_hostname_short }}
- delete interfaces lo0
provider: "{{ netconf }}"
- debug: msg="END netconf/basic.yaml"

View file

@ -1,43 +0,0 @@
---
- debug: msg="START netconf/force.yaml"
- name: setup
junos_config:
lines:
- set system host-name {{ inventory_hostname_short }}
- delete interfaces lo0
provider: "{{ netconf }}"
- name: configure basic config template
junos_template:
src: basic/config.j2
provider: "{{ netconf }}"
action: replace
register: result
- assert:
that:
- "result.changed == true"
- "'1.1.1.1/32' in result.diff.prepared"
- name: check basic config template idempotent
junos_template:
src: basic/config-update.j2
action: replace
provider: "{{ netconf }}"
register: result
- assert:
that:
- "result.changed == true"
- "'1.1.1.1/32' in result.diff.prepared"
- name: teardown
junos_config:
lines:
- set system host-name {{ inventory_hostname_short }}
- delete interfaces lo0
action: replace
provider: "{{ netconf }}"
- debug: msg="END netconf/force.yaml"

View file

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

View file

@ -1,2 +0,0 @@
dependencies:
- prepare_nxos_tests

View file

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

View file

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

View file

@ -1,28 +0,0 @@
---
- name: collect all nxapi test cases
find:
paths: "{{ role_path }}/tests/nxapi"
patterns: "{{ testcase }}.yaml"
register: test_cases
- name: set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
- name: enable nxapi
nxos_config:
lines:
- feature nxapi
- nxapi http port 80
provider: "{{ cli }}"
- name: run test case
include: "{{ test_case_to_run }}"
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run
- name: disable nxapi
nxos_config:
lines:
- no feature nxapi
provider: "{{ cli }}"

View file

@ -1,4 +0,0 @@
interface Ethernet2/5
description this is a test
shutdown

View file

@ -1,4 +0,0 @@
interface Ethernet2/5
description test description from ansible
shutdown

View file

@ -1,4 +0,0 @@
interface Ethernet2/5
description this is a test
no shutdown

View file

@ -1,4 +0,0 @@
interface Ethernet2/5
description this is a test
shutdown

View file

@ -1,50 +0,0 @@
---
- debug: msg="START cli/backup.yaml"
- name: setup
nxos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ cli }}"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure device with config
nxos_template:
src: basic/config.j2
backup: yes
provider: "{{ cli }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- debug: msg="END cli/backup.yaml"

View file

@ -1,36 +0,0 @@
---
- debug: msg="START cli/basic.yaml"
- name: setup
nxos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ cli }}"
- name: configure device with config
nxos_template:
src: basic/config.j2
provider: "{{ cli }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
nxos_template:
src: basic/config.j2
provider: "{{ cli }}"
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END cli/basic.yaml"

View file

@ -1,42 +0,0 @@
---
- debug: msg="START cli/defaults.yaml"
- name: setup
nxos_config:
commands:
- no description
- shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ cli }}"
- name: configure device with defaults included
nxos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ cli }}"
register: result
- debug: var=result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with defaults included
nxos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ cli }}"
register: result
- debug: var=result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END cli/defaults.yaml"

View file

@ -1,38 +0,0 @@
---
- debug: msg="START cli/force.yaml"
- name: setup
nxos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ cli }}"
- name: configure device with config
nxos_template:
src: basic/config.j2
provider: "{{ cli }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
nxos_template:
src: basic/config.j2
provider: "{{ cli }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- debug: msg="END cli/force.yaml"

View file

@ -1,50 +0,0 @@
---
- debug: msg="START nxapi/backup.yaml"
- name: setup
nxos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ nxapi }}"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- name: delete backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{backup_files.files|default([])}}"
- name: configure device with config
nxos_template:
src: basic/config.j2
backup: yes
provider: "{{ nxapi }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: collect any backup files
find:
paths: "{{ role_path }}/backup"
pattern: "{{ inventory_hostname_short }}_config*"
register: backup_files
delegate_to: localhost
- assert:
that:
- "backup_files.files is defined"
- debug: msg="END nxapi/backup.yaml"

View file

@ -1,36 +0,0 @@
---
- debug: msg="START nxapi/basic.yaml"
- name: setup
nxos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ nxapi }}"
- name: configure device with config
nxos_template:
src: basic/config.j2
provider: "{{ nxapi }}"
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
nxos_template:
src: basic/config.j2
provider: "{{ nxapi }}"
register: result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END nxapi/basic.yaml"

View file

@ -1,42 +0,0 @@
---
- debug: msg="START nxapi/defaults.yaml"
- name: setup
nxos_config:
commands:
- no description
- shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ nxapi }}"
- name: configure device with defaults included
nxos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ nxapi }}"
register: result
- debug: var=result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with defaults included
nxos_template:
src: defaults/config.j2
include_defaults: yes
provider: "{{ nxapi }}"
register: result
- debug: var=result
- assert:
that:
- "result.changed == false"
- "result.updates is defined"
- debug: msg="END nxapi/defaults.yaml"

View file

@ -1,38 +0,0 @@
---
- debug: msg="START nxapi/force.yaml"
- name: setup
nxos_config:
commands:
- no description
- no shutdown
parents:
- interface Ethernet2/5
match: none
provider: "{{ nxapi }}"
- name: configure device with config
nxos_template:
src: basic/config.j2
provider: "{{ nxapi }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- name: check device with config
nxos_template:
src: basic/config.j2
provider: "{{ nxapi }}"
force: yes
register: result
- assert:
that:
- "result.changed == true"
- "result.updates is defined"
- debug: msg="END nxapi/force.yaml"

View file

@ -298,7 +298,6 @@ lib/ansible/modules/network/cumulus/_cl_ports.py
lib/ansible/modules/network/cumulus/nclu.py lib/ansible/modules/network/cumulus/nclu.py
lib/ansible/modules/net_tools/dnsimple.py lib/ansible/modules/net_tools/dnsimple.py
lib/ansible/modules/net_tools/dnsmadeeasy.py lib/ansible/modules/net_tools/dnsmadeeasy.py
lib/ansible/modules/network/eos/_eos_template.py
lib/ansible/modules/network/eos/eos_banner.py lib/ansible/modules/network/eos/eos_banner.py
lib/ansible/modules/network/eos/eos_command.py lib/ansible/modules/network/eos/eos_command.py
lib/ansible/modules/network/eos/eos_config.py lib/ansible/modules/network/eos/eos_config.py
@ -312,13 +311,11 @@ lib/ansible/modules/network/fortios/fortios_config.py
lib/ansible/modules/network/fortios/fortios_ipv4_policy.py lib/ansible/modules/network/fortios/fortios_ipv4_policy.py
lib/ansible/modules/network/illumos/dladm_iptun.py lib/ansible/modules/network/illumos/dladm_iptun.py
lib/ansible/modules/network/illumos/dladm_linkprop.py lib/ansible/modules/network/illumos/dladm_linkprop.py
lib/ansible/modules/network/ios/_ios_template.py
lib/ansible/modules/network/ios/ios_banner.py lib/ansible/modules/network/ios/ios_banner.py
lib/ansible/modules/network/ios/ios_command.py lib/ansible/modules/network/ios/ios_command.py
lib/ansible/modules/network/ios/ios_facts.py lib/ansible/modules/network/ios/ios_facts.py
lib/ansible/modules/network/ios/ios_system.py lib/ansible/modules/network/ios/ios_system.py
lib/ansible/modules/network/ios/ios_vrf.py lib/ansible/modules/network/ios/ios_vrf.py
lib/ansible/modules/network/iosxr/_iosxr_template.py
lib/ansible/modules/network/iosxr/iosxr_command.py lib/ansible/modules/network/iosxr/iosxr_command.py
lib/ansible/modules/network/iosxr/iosxr_config.py lib/ansible/modules/network/iosxr/iosxr_config.py
lib/ansible/modules/network/iosxr/iosxr_facts.py lib/ansible/modules/network/iosxr/iosxr_facts.py
@ -337,7 +334,6 @@ lib/ansible/modules/network/netvisor/pn_vrouterif.py
lib/ansible/modules/network/netvisor/pn_vrouterlbif.py lib/ansible/modules/network/netvisor/pn_vrouterlbif.py
lib/ansible/modules/net_tools/nmcli.py lib/ansible/modules/net_tools/nmcli.py
lib/ansible/modules/network/nxos/_nxos_mtu.py lib/ansible/modules/network/nxos/_nxos_mtu.py
lib/ansible/modules/network/nxos/_nxos_template.py
lib/ansible/modules/network/nxos/nxos_aaa_server.py lib/ansible/modules/network/nxos/nxos_aaa_server.py
lib/ansible/modules/network/nxos/nxos_aaa_server_host.py lib/ansible/modules/network/nxos/nxos_aaa_server_host.py
lib/ansible/modules/network/nxos/nxos_command.py lib/ansible/modules/network/nxos/nxos_command.py
@ -374,7 +370,6 @@ lib/ansible/modules/network/nxos/nxos_vtp_domain.py
lib/ansible/modules/network/nxos/nxos_vtp_password.py lib/ansible/modules/network/nxos/nxos_vtp_password.py
lib/ansible/modules/network/nxos/nxos_vtp_version.py lib/ansible/modules/network/nxos/nxos_vtp_version.py
lib/ansible/modules/net_tools/omapi_host.py lib/ansible/modules/net_tools/omapi_host.py
lib/ansible/modules/network/openswitch/_ops_template.py
lib/ansible/modules/network/openswitch/ops_command.py lib/ansible/modules/network/openswitch/ops_command.py
lib/ansible/modules/network/openswitch/ops_config.py lib/ansible/modules/network/openswitch/ops_config.py
lib/ansible/modules/network/openswitch/ops_facts.py lib/ansible/modules/network/openswitch/ops_facts.py

View file

@ -1,12 +0,0 @@
!
hostname router
!
interface GigabitEthernet0/0
ip address 1.2.3.4 255.255.255.0
description test string
!
interface GigabitEthernet0/1
ip address 6.7.8.9 255.255.255.0
description test string
shutdown
!

View file

@ -1,13 +0,0 @@
!
hostname router
!
interface GigabitEthernet0/0
ip address 1.2.3.4 255.255.255.0
description test string
no shutdown
!
interface GigabitEthernet0/1
ip address 6.7.8.9 255.255.255.0
description test string
shutdown
!

View file

@ -1,11 +0,0 @@
!
hostname foo
!
interface GigabitEthernet0/0
no ip address
!
interface GigabitEthernet0/1
ip address 6.7.8.9 255.255.255.0
description test string
shutdown
!

View file

@ -1,87 +0,0 @@
#
# (c) 2016 Red Hat 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/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import json
from ansible.compat.tests.mock import patch
from ansible.modules.network.ios import _ios_template
from .ios_module import TestIosModule, load_fixture, set_module_args
class TestIosTemplateModule(TestIosModule):
module = _ios_template
def setUp(self):
self.mock_get_config = patch('ansible.modules.network.ios._ios_template.get_config')
self.get_config = self.mock_get_config.start()
self.mock_load_config = patch('ansible.modules.network.ios._ios_template.load_config')
self.load_config = self.mock_load_config.start()
def tearDown(self):
self.mock_get_config.stop()
self.mock_load_config.stop()
def load_fixtures(self, commands=None):
config_file = 'ios_template_config.cfg'
self.get_config.return_value = load_fixture(config_file)
self.load_config.return_value = None
def test_ios_template_unchanged(self):
src = load_fixture('ios_template_config.cfg')
set_module_args(dict(src=src))
self.execute_module()
def test_ios_template_simple(self):
src = load_fixture('ios_template_src.cfg')
set_module_args(dict(src=src))
commands = ['hostname foo',
'interface GigabitEthernet0/0',
'no ip address']
self.execute_module(changed=True, commands=commands)
def test_ios_template_force(self):
src = load_fixture('ios_template_config.cfg')
set_module_args(dict(src=src, force=True))
commands = [str(s).strip() for s in src.split('\n') if s and s != '!']
self.execute_module(changed=True, commands=commands)
self.assertFalse(self.get_config.called)
def test_ios_template_backup(self):
set_module_args(dict(backup=True))
result = self.execute_module()
self.assertIn('__backup__', result)
def test_ios_template_config(self):
src = load_fixture('ios_template_config.cfg')
config = 'hostname router'
set_module_args(dict(src=src, config=config))
commands = ['interface GigabitEthernet0/0',
'ip address 1.2.3.4 255.255.255.0',
'description test string',
'interface GigabitEthernet0/1',
'ip address 6.7.8.9 255.255.255.0',
'description test string',
'shutdown']
self.execute_module(changed=True, commands=commands)
self.assertFalse(self.get_config.called)

View file

@ -1,12 +0,0 @@
!
hostname router
!
interface GigabitEthernet0/0
ip address 1.2.3.4 255.255.255.0
description test string
!
interface GigabitEthernet0/1
ip address 6.7.8.9 255.255.255.0
description test string
shutdown
!

View file

@ -1,11 +0,0 @@
!
hostname foo
!
interface GigabitEthernet0/0
no ip address
!
interface GigabitEthernet0/1
ip address 6.7.8.9 255.255.255.0
description test string
shutdown
!

View file

@ -1,87 +0,0 @@
#
# (c) 2016 Red Hat 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/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import json
from ansible.compat.tests.mock import patch
from .iosxr_module import TestIosxrModule, load_fixture, set_module_args
from ansible.modules.network.iosxr import _iosxr_template
class TestIosxrTemplateModule(TestIosxrModule):
module = _iosxr_template
def setUp(self):
self.mock_get_config = patch('ansible.modules.network.iosxr._iosxr_template.get_config')
self.get_config = self.mock_get_config.start()
self.mock_load_config = patch('ansible.modules.network.iosxr._iosxr_template.load_config')
self.load_config = self.mock_load_config.start()
def tearDown(self):
self.mock_get_config.stop()
self.mock_load_config.stop()
def load_fixtures(self, commands=None):
config_file = 'iosxr_template_config.cfg'
self.get_config.return_value = load_fixture(config_file)
self.load_config.return_value = None
def test_iosxr_template_unchanged(self):
src = load_fixture('iosxr_template_config.cfg')
set_module_args(dict(src=src))
self.execute_module()
def test_iosxr_template_simple(self):
src = load_fixture('iosxr_template_src.cfg')
set_module_args(dict(src=src))
commands = ['hostname foo',
'interface GigabitEthernet0/0',
'no ip address']
self.execute_module(changed=True, commands=commands)
def test_iosxr_template_force(self):
src = load_fixture('iosxr_template_config.cfg')
set_module_args(dict(src=src, force=True))
commands = [str(s).strip() for s in src.split('\n') if s and s != '!']
self.execute_module(changed=True, commands=commands)
self.assertFalse(self.get_config.called)
def test_iosxr_template_backup(self):
set_module_args(dict(backup=True))
result = self.execute_module()
self.assertIn('__backup__', result)
def test_iosxr_template_config(self):
src = load_fixture('iosxr_template_config.cfg')
config = 'hostname router'
set_module_args(dict(src=src, config=config))
commands = ['interface GigabitEthernet0/0',
'ip address 1.2.3.4 255.255.255.0',
'description test string',
'interface GigabitEthernet0/1',
'ip address 6.7.8.9 255.255.255.0',
'description test string',
'shutdown']
self.execute_module(changed=False)
self.assertTrue(self.get_config.called)