initial add of junos shared module

This commit adds a new shared module for working with network devices running
the Juniper Junos operating system.  The commit includes a new document
fragment junos to be used when building modules.  The junos shared module
currently only supports CLI
This commit is contained in:
Peter Sprygada 2016-01-10 10:33:00 -05:00
parent c9a5f7ea7e
commit e709095f53
2 changed files with 178 additions and 0 deletions

View file

@ -0,0 +1,126 @@
#
# (c) 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/>.
#
NET_COMMON_ARGS = dict(
host=dict(required=True),
port=dict(default=22, type='int'),
username=dict(required=True),
password=dict(no_log=True)
)
def to_list(val):
if isinstance(val, (list, tuple)):
return list(val)
elif val is not None:
return [val]
else:
return list()
class Cli(object):
def __init__(self, module):
self.module = module
self.shell = None
def connect(self, **kwargs):
host = self.module.params['host']
port = self.module.params['port'] or 22
username = self.module.params['username']
password = self.module.params['password']
self.shell = Shell()
self.shell.open(host, port=port, username=username, password=password)
def send(self, commands):
return self.shell.send(commands)
class JunosModule(AnsibleModule):
def __init__(self, *args, **kwargs):
super(JunosModule, self).__init__(*args, **kwargs)
self.connection = None
self._config = None
@property
def config(self):
if not self._config:
self._config = self.get_config()
return self._config
def connect(self):
try:
self.connection = Cli(self)
self.connection.connect()
self.execute('cli')
self.execute('set cli screen-length 0')
except ShellErrror, exc:
self.fail_json(msg=str(exc))
def configure(self, commands):
commands = to_list(commands)
commands.insert(0, 'configure')
commands.append('commit and-quit')
responses = self.execute(commands)
responses.pop(0)
responses.pop()
return responses
def execute(self, commands, **kwargs):
try:
return self.connection.send(commands)
except ShellError, exc:
self.fail_json(msg=exc.message)
def disconnect(self):
self.connection.close()
def parse_config(self, cfg):
return parse(cfg, indent=4)
def get_config(self):
cmd = 'show configuration'
return self.execute(cmd)[0]
def get_module(**kwargs):
"""Return instance of JunosModule
"""
argument_spec = NET_COMMON_ARGS.copy()
if kwargs.get('argument_spec'):
argument_spec.update(kwargs['argument_spec'])
kwargs['argument_spec'] = argument_spec
kwargs['check_invalid_arguments'] = False
module = JunosModule(**kwargs)
# HAS_PARAMIKO is set by module_utils/shell.py
if not HAS_PARAMIKO:
module.fail_json(msg='paramiko is required but does not appear to be installed')
# copy in values from local action.
params = json_dict_unicode_to_bytes(json.loads(MODULE_COMPLEX_ARGS))
for key, value in params.iteritems():
module.params[key] = value
module.connect()
return module

View file

@ -0,0 +1,52 @@
#
# (c) 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/>.
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 buiding the connection to the remote
device. The port value will default to the well known SSH port
of 22
required: false
default: 22
username:
description:
- Configures the usename to use to authenticate the connection to
the remote device. The value of I(username) is used to authenticate
the SSH session
required: true
password:
description:
- Specifies the password to use when authentication the connection to
the remote device. The value of I(password) is used to authenticate
the SSH session
required: false
default: null
"""