diff --git a/CHANGELOG.md b/CHANGELOG.md index e62c75e67f4..b256e467f70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,9 @@ Ansible Changes By Release * vmware_local_user_manager * vmware_vmotion - wakeonlan +- Dell Networking + * dnos10_command + * dnos10_config ###Minor Changes: * now -vvv shows exact path from which 'currently executing module' was picked up from. diff --git a/lib/ansible/module_utils/dnos10.py b/lib/ansible/module_utils/dnos10.py new file mode 100644 index 00000000000..9aeaa1be057 --- /dev/null +++ b/lib/ansible/module_utils/dnos10.py @@ -0,0 +1,119 @@ +# 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. +# +# 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. +# + +import re + +from ansible.module_utils.network import register_transport, to_list +from ansible.module_utils.shell import CliBase +from ansible.module_utils.netcfg import NetworkConfig, ConfigLine + + +def get_config(module): + contents = module.params['config'] + + if not contents: + contents = module.config.get_config() + module.params['config'] = contents + + return NetworkConfig(indent=1, contents=contents[0]) + + +def get_sublevel_config(running_config, module): + contents = list() + current_config_contents = list() + obj = running_config.get_object(module.params['parents']) + if obj: + contents = obj.children + contents[:0] = module.params['parents'] + + for c in contents: + if isinstance(c, str): + current_config_contents.append(c) + if isinstance(c, ConfigLine): + current_config_contents.append(c.raw) + sublevel_config = '\n'.join(current_config_contents) + + return sublevel_config + + +class Cli(CliBase): + + NET_PASSWD_RE = re.compile(r"[\r\n]?password:\s?$", re.I) + + CLI_PROMPTS_RE = [ + re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), + re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$") + ] + + CLI_ERRORS_RE = [ + re.compile(r"% ?Error"), + re.compile(r"% ?Bad secret"), + re.compile(r"Syntax error:"), + re.compile(r"invalid input", re.I), + re.compile(r"(?:incomplete|ambiguous) command", re.I), + re.compile(r"connection timed out", re.I), + re.compile(r"[^\r\n]+ not found", re.I), + re.compile(r"'[^']' +returned error code: ?\d+"), + ] + + + def connect(self, params, **kwargs): + super(Cli, self).connect(params, kickstart=False, **kwargs) + self.shell.send('terminal length 0') + + + def configure(self, commands, **kwargs): + cmds = ['configure terminal'] + cmds.extend(to_list(commands)) + cmds.append('end') + cmds.append('commit') + + responses = self.execute(cmds) + responses.pop(0) + return responses + + + def get_config(self, **kwargs): + return self.execute(['show running-configuration']) + + + def load_config(self, commands, **kwargs): + return self.configure(commands) + + + def commit_config(self, **kwargs): + self.execute(['commit']) + + + def abort_config(self, **kwargs): + self.execute(['discard']) + + + def save_config(self): + self.execute(['copy running-config startup-config']) + + +Cli = register_transport('cli', default=True)(Cli) diff --git a/lib/ansible/plugins/action/dnos10_config.py b/lib/ansible/plugins/action/dnos10_config.py new file mode 100644 index 00000000000..13bcd553451 --- /dev/null +++ b/lib/ansible/plugins/action/dnos10_config.py @@ -0,0 +1,26 @@ +# +# 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 . +# +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.action import ActionBase +from ansible.plugins.action.net_config import ActionModule as NetActionModule + +class ActionModule(NetActionModule, ActionBase): + pass + + diff --git a/lib/ansible/utils/module_docs_fragments/dnos10.py b/lib/ansible/utils/module_docs_fragments/dnos10.py new file mode 100644 index 00000000000..567de5fa82b --- /dev/null +++ b/lib/ansible/utils/module_docs_fragments/dnos10.py @@ -0,0 +1,67 @@ +# 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 . + + +class ModuleDocFragment(object): + + # Standard files documentation fragment + DOCUMENTATION = """ +options: + host: + description: + - Specifies the DNS host name or address for connecting to the remote + device over the specified transport. The value of host is used as + the destination address for the transport. + required: true + port: + description: + - Specifies the port to use when building the connection to the remote + device. + required: false + default: 22 + username: + description: + - This value I(username) is used to authenticate the SSH session to the + remote device. If the value is not specified in the task, the + value of environment variable ANSIBLE_NET_USERNAME will be used instead. + required: false + password: + description: + - This value I(password) is used to authenticate the SSH session to + the remote device. If the value is not specified in the task, the + value of environment variable ANSIBLE_NET_PASSWORD will be used instead. + required: false + default: null + ssh_keyfile: + description: + - This value I(ssh_keyfile) is the path to the key used to authenticate + the SSH session to the remote device. If the value is not specified + in the task, the value of environment variable ANSIBLE_NET_SSH_KEYFILE + will be used instead. + required: false + timeout: + description: + - Specifies idle timeout (in seconds) for the connection. Useful if the + console freezes before continuing. For example when saving + configurations. + required: false + default: 10 + provider: + description: + - Convenience method that allows all M(dnos10) arguments to be passed as + a dict object. All constraints (required, choices, etc) must be + met either by individual arguments or values in this dict. + required: false + default: null +"""