new module

pull/58969/head
shashik 7 years ago
parent e8f4ebb22c
commit f86b5b3120

@ -0,0 +1,102 @@
# This code is part of Ansible, but is an independent component.
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
#
# (c) 2016 Red Hat Inc.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
from ansible.module_utils._text import to_text
from ansible.module_utils.basic import env_fallback
from ansible.module_utils.network.common.utils import to_list
from ansible.module_utils.connection import Connection, ConnectionError
_DEVICE_CONFIGS = {}
def get_connection(module):
return Connection(module._socket_path)
def load_config(module, commands):
connection = get_connection(module)
try:
resp = connection.edit_config(candidate=commands)
return resp.get('response')
except ConnectionError as exc:
module.fail_json(msg=to_text(exc))
def run_commands(module, commands, check_rc=True):
connection = get_connection(module)
try:
return connection.run_commands(commands=commands, check_rc=check_rc)
except ConnectionError as exc:
module.fail_json(msg=to_text(exc))
def exec_scp(module, command):
connection = Connection(module._socket_path)
return connection.scp(**command)
def get_config(module, flags=None, compare=None):
flag_str = ' '.join(to_list(flags))
try:
return _DEVICE_CONFIGS[flag_str]
except KeyError:
connection = get_connection(module)
try:
out = connection.get_config(flags=flags, compare=compare)
except ConnectionError as exc:
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
cfg = to_text(out, errors='surrogate_then_replace').strip()
_DEVICE_CONFIGS[flag_str] = cfg
return cfg
def check_args(module, warnings):
pass
def get_defaults_flag(module):
connection = get_connection(module)
try:
out = connection.get_defaults_flag()
except ConnectionError as exc:
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
return to_text(out, errors='surrogate_then_replace').strip()
def get_env_diff(module, compare=None):
connection = get_connection(module)
try:
out = connection.get_env_diff(compare)
except ConnectionError as exc:
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
return out

@ -0,0 +1,217 @@
#!/usr/bin/python
# Copyright: Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'network'}
DOCUMENTATION = """
---
module: icx_banner
version_added: "2.9"
author: "Ruckus Wireless (@Commscope)"
short_description: Manage multiline banners on Ruckus ICX 7000 series switches
description:
- This will configure both login and motd banners on remote
ruckus ICX 7000 series switches. It allows playbooks to add or remove
banner text from the active running configuration.
options:
banner:
description:
- Specifies which banner should be configured on the remote device.
type: str
required: true
choices: ['motd', 'exec', 'incoming']
text:
description:
- The banner text that should be
present in the remote device running configuration.
This argument accepts a multiline string, with no empty lines.
type: str
state:
description:
- Specifies whether or not the configuration is
present in the current devices active running configuration.
type: str
default: present
choices: ['present', 'absent']
enterkey:
description:
- Specifies whether or not the motd configuration should accept
the require-enter-key
type: bool
default: no
check_running_config:
description:
- Check running configuration. This can be set as environment variable.
Module will use environment variable value(default:True), unless it is overriden,
by specifying it as module parameter.
type: bool
default: yes
"""
EXAMPLES = """
- name: configure the motd banner
icx_banner:
banner: motd
text: |
this is my motd banner
that contains a multiline
string
state: present
- name: remove the motd banner
icx_banner:
banner: motd
state: absent
- name: configure require-enter-key for motd
icx_banner:
banner: motd
enterkey: True
- name: remove require-enter-key for motd
icx_banner:
banner: motd
enterkey: False
"""
RETURN = """
commands:
description: The list of configuration mode commands to send to the device
returned: always
type: list
sample:
- banner motd
- this is my motd banner
- that contains a multiline
- string
"""
import re
from ansible.module_utils._text import to_text
from ansible.module_utils.connection import exec_command
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.icx.icx import load_config, get_config, get_env_diff
from ansible.module_utils.connection import Connection, ConnectionError
def map_obj_to_commands(updates, module):
commands = list()
state = module.params['state']
want, have = updates
if module.params['banner'] != 'motd' and module.params['enterkey']:
module.fail_json(msg=module.params['banner'] + " banner can have text only, got enterkey")
if state == 'absent':
if 'text' in have.keys() and have['text']:
commands.append('no banner %s' % module.params['banner'])
if(module.params['enterkey'] is False):
commands.append('no banner %s require-enter-key' % module.params['banner'])
elif state == 'present':
if module.params['text'] is None and module.params['enterkey'] is None:
module.fail_json(msg=module.params['banner'] + " one of the following is required: text, enterkey:only if motd")
if module.params["banner"] == "motd" and want['enterkey'] != have['enterkey']:
if(module.params['enterkey']):
commands.append('banner %s require-enter-key' % module.params['banner'])
if want['text'] and (want['text'] != have.get('text')):
module.params["enterkey"] = None
banner_cmd = 'banner %s' % module.params['banner']
banner_cmd += ' $\n'
banner_cmd += module.params['text'].strip()
banner_cmd += '\n$'
commands.append(banner_cmd)
return commands
def map_config_to_obj(module):
compare = module.params.get('check_running_config')
obj = {'banner': module.params['banner'], 'state': 'absent', 'enterkey': False}
exec_command(module, 'skip')
output_text = ''
output_re = ''
out = get_config(module, flags=['| begin banner %s'
% module.params['banner']], compare=module.params['check_running_config'])
if out:
try:
output_re = re.search(r'banner %s( require-enter-key)' % module.params['banner'], out, re.S).group(0)
obj['enterkey'] = True
except BaseException:
pass
try:
output_text = re.search(r'banner %s (\$([^\$])+\$){1}' % module.params['banner'], out, re.S).group(1).strip('$\n')
except BaseException:
pass
else:
output_text = None
if output_text:
obj['text'] = output_text
obj['state'] = 'present'
if get_env_diff(module, module.params['check_running_config']) is False:
obj = {'banner': module.params['banner'], 'state': 'absent', 'enterkey': False, 'text': 'JUNK'}
return obj
def map_params_to_obj(module):
text = module.params['text']
if text:
text = str(text).strip()
return {
'banner': module.params['banner'],
'text': text,
'state': module.params['state'],
'enterkey': module.params['enterkey']
}
def main():
"""entry point for module execution
"""
argument_spec = dict(
banner=dict(required=True, choices=['motd', 'exec', 'incoming']),
text=dict(),
enterkey=dict(type='bool'),
state=dict(default='present', choices=['present', 'absent']),
check_running_config=dict(default=True, type='bool')
)
required_one_of = [['text', 'enterkey', 'state']]
module = AnsibleModule(argument_spec=argument_spec,
required_one_of=required_one_of,
supports_check_mode=True)
warnings = list()
results = {'changed': False}
want = map_params_to_obj(module)
have = map_config_to_obj(module)
# results['want']=want
# results['have']=have
commands = map_obj_to_commands((want, have), module)
results['commands'] = commands
if commands:
if not module.check_mode:
response = load_config(module, commands)
results['changed'] = True
module.exit_json(**results)
if __name__ == '__main__':
main()
Loading…
Cancel
Save