ansible/network/junos/junos_config.py
Peter Sprygada 5814748b4d add support for netconf to junos_config
The junos_config module now supports the netconf transport.
2016-04-24 14:12:06 -04:00

241 lines
7.9 KiB
Python

#!/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/>.
#
DOCUMENTATION = """
---
module: junos_config
version_added: "2.1"
author: "Peter Sprygada (@privateip)"
short_description: Manage configuration on remote devices running Junos
description:
- The M(junos_config) module provides an abstraction for working
with the configuration running on remote devices. It can perform
operations that influence the confiugration state.
- This module provides an implementation for configuring Juniper
JUNOS devices. The configuration statements must start with either
`set` or `delete` and are compared against the current device
configuration and only changes are pushed to the device.
extends_documentation_fragment: junos
options:
lines:
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
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"]
rollback:
description:
- The C(rollback) argument instructs the module to rollback the
current configuration to the identifier specified in the
argument. If the specified rollback identifier does not
exist on the remote device, the module will fail. To rollback
to the most recent commit, set the C(rollback) argument to 0
required: false
default: null
zeroize:
description:
- The C(zeroize) argument is used to completely ssantaize the
remote device configuration back to initial defaults. This
argument will effectively remove all current configuration
statements on the remote device
required: false
default: null
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_config
action:
description:
- The C(action) argument instructs the module how to load the
configuration into the remote device. When action is set to
I(merge) the C(src) template file is merged with the current
device configuration. When the I(replace) action is used,
the current device configuration is replaced by the C(src).
Finally when C(overwrite) is used, the device configuration will
be overwritten.
required: true
default: merge
choices: ['merge', 'replace', 'overwrite']
replace:
description:
- The C(replace) argument will instruct the remote device to
replace the current configuration hierarchy with the one specified
in the corresponding hierarchy of the source configuraiton loaded
from this module.
required: true
default: false
overwrite:
description:
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: text
choices: ['text', 'xml', 'set']
requirements:
- junos-eznc
notes:
- This module requires the netconf system service be enabled on
the remote device being managed
"""
EXAMPLES = """
- name: load configuration lines in device
junos_config:
lines:
- set system host-name {{ inventory_hostname }}
- delete interfaces ge-0/0/0 description
comment: update config
- name: rollback the configuration to id 10
junos_config:
rollback: 10
- name: zero out the current configuration
junos_config:
zeroize: yes
- name: confirm a candidate configuration
junos_config:
"""
import re
DEFAULT_COMMENT = 'configured by junos_config'
def diff_config(candidate, config):
updates = set()
for line in candidate:
parts = line.split()
action = parts[0]
cfgline = ' '.join(parts[1:])
if action not in ['set', 'delete']:
module.fail_json(msg='line must start with either `set` or `delete`')
elif action == 'set' and cfgline not in config:
updates.add(line)
elif action == 'delete' and not config:
updates.add(line)
elif action == 'delete':
for cfg in config:
if cfg.startswith(cfgline):
updates.add(cfgline)
return list(updates)
def main():
argument_spec = dict(
lines=dict(type='list'),
rollback=dict(type='int'),
zeroize=dict(default=False, type='bool'),
confirm=dict(default=0, type='int'),
comment=dict(default=DEFAULT_COMMENT),
replace=dict(default=False, type='bool'),
transport=dict(default='netconf', choices=['netconf'])
)
mutually_exclusive = [('lines', 'rollback'), ('lines', 'zeroize'),
('rollback', 'zeroize')]
module = get_module(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
rollback = module.params['rollback']
zeroize = module.params['zeroize']
comment = module.params['comment']
confirm = module.params['confirm']
if module.params['replace']:
action = 'replace'
else:
action = 'merge'
lines = module.params['lines']
commit = not module.check_mode
results = dict(changed=False)
if lines:
config = str(module.get_config(config_format='set')).split('\n')
updates = diff_config(lines, config)
if updates:
updates = '\n'.join(updates)
diff = module.load_config(updates, action=action, comment=comment,
format='set', commit=commit, confirm=confirm)
if diff:
results['changed'] = True
results['diff'] = dict(prepared=diff)
elif rollback is not None:
diff = module.rollback_config(rollback, commit=commit)
if diff:
results['changed'] = True
results['diff'] = dict(prepared=diff)
elif zeroize:
if not module.check_mode:
module.run_commands('request system zeroize')
results['changed'] = True
module.exit_json(**results)
from ansible.module_utils.basic import *
from ansible.module_utils.junos import *
if __name__ == '__main__':
main()