community.general/lib/ansible/modules/network/nxos/nxos_smu.py
Peter Sprygada 21d993a4b8 refactors nxos module to use persistent connections (#21470)
This completes the refactor of the nxos modules to use the persistent
connection.  It also updates all of the nxos modules to use the
new connection module and preserves use of nxapi as well.
2017-02-15 11:43:09 -05:00

194 lines
6 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/>.
#
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'version': '1.0'}
DOCUMENTATION = '''
---
module: nxos_smu
version_added: "2.2"
short_description: Perform SMUs on Cisco NX-OS devices.
description:
- Perform software maintenance upgrades (SMUs) on Cisco NX-OS devices.
author: Gabriele Gerbino (@GGabriele)
notes:
- The module can only activate and commit a package,
not remove or deactivate it.
- Use C(transport=nxapi) to avoid connection timeout
options:
pkg:
description:
- Name of the remote package.
required: true
file_system:
description:
- The remote file system of the device. If omitted,
devices that support a file_system parameter will use
their default values.
required: false
default: null
'''
EXAMPLES = '''
- nxos_smu:
pkg: "nxos.CSCuz65185-n9k_EOR-1.0.0-7.0.3.I2.2d.lib32_n9000.rpm"
username: "{{ un }}"
password: "{{ pwd }}"
host: "{{ inventory_hostname }}"
'''
RETURN = '''
file_system:
description: The remote file system of the device.
returned: always
type: string
sample: "bootflash:"
pkg:
description: Name of the remote package
type: string
returned: always
sample: "nxos.CSCuz65185-n9k_EOR-1.0.0-7.0.3.I2.2d.lib32_n9000.rpm"
updates:
description: commands sent to the device
returned: always
type: list
sample: ["install add bootflash:nxos.CSCuz65185-n9k_EOR-1.0.0-7.0.3.I2.2d.lib32_n9000.rpm",
"install activate bootflash:nxos.CSCuz65185-n9k_EOR-1.0.0-7.0.3.I2.2d.lib32_n9000.rpm force",
"install commit bootflash:nxos.CSCuz65185-n9k_EOR-1.0.0-7.0.3.I2.2d.lib32_n9000.rpm"]
changed:
description: check to see if a change was made on the device
returned: always
type: boolean
sample: true
'''
from ansible.module_utils.nxos import get_config, load_config, run_commands
from ansible.module_utils.nxos import nxos_argument_spec, check_args
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.netcfg import CustomNetworkConfig
import time
import collections
import re
import re
def execute_show_command(command, module, command_type='cli_show'):
if module.params['transport'] == 'cli':
cmds = [command]
body = run_commands(module, cmds)
elif module.params['transport'] == 'nxapi':
cmds = [command]
body = run_commands(module, cmds)
return body
def remote_file_exists(module, dst, file_system='bootflash:'):
command = 'dir {0}/{1}'.format(file_system, dst)
body = execute_show_command(command, module, command_type='cli_show_ascii')
if 'No such file' in body[0]:
return False
return True
def apply_patch(module, commands):
for command in commands:
load_config(module, [command])
time.sleep(5)
if 'failed' in response:
module.fail_json(msg="Operation failed!", response=response)
def get_commands(module, pkg, file_system):
commands = []
splitted_pkg = pkg.split('.')
fixed_pkg = '.'.join(splitted_pkg[0:-1])
command = 'show install inactive'
inactive_body = execute_show_command(command, module,
command_type='cli_show_ascii')
command = 'show install active'
active_body = execute_show_command(command, module,
command_type='cli_show_ascii')
if fixed_pkg not in inactive_body[0] and fixed_pkg not in active_body[0]:
commands.append('install add {0}{1}'.format(file_system, pkg))
if fixed_pkg not in active_body[0]:
commands.append('install activate {0}{1} force'.format(
file_system, pkg))
command = 'show install committed'
install_body = execute_show_command(command, module,
command_type='cli_show_ascii')
if fixed_pkg not in install_body[0]:
commands.append('install commit {0}{1}'.format(file_system, pkg))
return commands
def main():
argument_spec = dict(
pkg=dict(required=True),
file_system=dict(required=False, default='bootflash:'),
include_defaults=dict(default=False),
config=dict(),
save=dict(type='bool', default=False)
)
argument_spec.update(nxos_argument_spec)
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
warnings = list()
check_args(module, warnings)
pkg = module.params['pkg']
file_system = module.params['file_system']
changed = False
remote_exists = remote_file_exists(module, pkg, file_system=file_system)
if not remote_exists:
module.fail_json(msg="The requested package doesn't exist "
"on the device")
commands = get_commands(module, pkg, file_system)
if not module.check_mode and commands:
try:
apply_patch(module, commands)
changed = True
except ShellError:
e = get_exception()
module.fail_json(msg=str(e))
if 'configure' in commands:
commands.pop(0)
module.exit_json(changed=changed,
pkg=pkg,
file_system=file_system,
updates=commands)
if __name__ == '__main__':
main()