|
| 1 | +# |
| 2 | +# (c) 2018 Red Hat Inc. |
| 3 | +# |
| 4 | +# This file is part of Ansible |
| 5 | +# |
| 6 | +# Ansible is free software: you can redistribute it and/or modify |
| 7 | +# it under the terms of the GNU General Public License as published by |
| 8 | +# the Free Software Foundation, either version 3 of the License, or |
| 9 | +# (at your option) any later version. |
| 10 | +# |
| 11 | +# Ansible is distributed in the hope that it will be useful, |
| 12 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | +# GNU General Public License for more details. |
| 15 | +# |
| 16 | +# You should have received a copy of the GNU General Public License |
| 17 | +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. |
| 18 | +# |
| 19 | +from __future__ import (absolute_import, division, print_function) |
| 20 | +__metaclass__ = type |
| 21 | + |
| 22 | +import json |
| 23 | +import re |
| 24 | + |
| 25 | +from ansible import constants as C |
| 26 | +from ansible.module_utils._text import to_text, to_bytes |
| 27 | +from ansible.errors import AnsibleConnectionFailure, AnsibleError |
| 28 | +from ansible.plugins.netconf import NetconfBase |
| 29 | +from ansible.plugins.netconf import ensure_connected |
| 30 | + |
| 31 | +try: |
| 32 | + from ncclient import manager |
| 33 | + from ncclient.operations import RPCError |
| 34 | + from ncclient.transport.errors import SSHUnknownHostError |
| 35 | + from ncclient.xml_ import to_ele, to_xml, new_ele |
| 36 | +except ImportError: |
| 37 | + raise AnsibleError("ncclient is not installed") |
| 38 | + |
| 39 | +try: |
| 40 | + from lxml import etree |
| 41 | +except ImportError: |
| 42 | + raise AnsibleError("lxml is not installed") |
| 43 | + |
| 44 | + |
| 45 | +class Netconf(NetconfBase): |
| 46 | + def get_text(self, ele, tag): |
| 47 | + try: |
| 48 | + return to_text(ele.find(tag).text, errors='surrogate_then_replace').strip() |
| 49 | + except AttributeError: |
| 50 | + pass |
| 51 | + |
| 52 | + def get_device_info(self): |
| 53 | + device_info = dict() |
| 54 | + device_info['network_os'] = 'sros' |
| 55 | + |
| 56 | + xmlns = "urn:nokia.com:sros:ns:yang:sr:state" |
| 57 | + f = '<state xmlns="%s"><system><platform/><bootup/><version/><lldp/></system></state>' % xmlns |
| 58 | + reply = to_ele(self.m.get(filter=('subtree', f)).data_xml) |
| 59 | + |
| 60 | + device_info['network_os_hostname'] = reply.findtext('.//{%s}state/{*}system/{*}lldp/{*}system-name' % xmlns) |
| 61 | + device_info['network_os_version'] = reply.findtext('.//{%s}state/{*}system/{*}version/{*}version-number' % xmlns) |
| 62 | + device_info['network_os_model'] = reply.findtext('.//{%s}state/{*}system/{*}platform' % xmlns) |
| 63 | + device_info['network_os_platform'] = 'Nokia 7x50' |
| 64 | + return device_info |
| 65 | + |
| 66 | + def get_capabilities(self): |
| 67 | + result = dict() |
| 68 | + result['rpc'] = self.get_base_rpc() + ['commit', 'discard_changes', 'validate', 'lock', 'unlock'] |
| 69 | + result['network_api'] = 'netconf' |
| 70 | + result['device_info'] = self.get_device_info() |
| 71 | + result['server_capabilities'] = [c for c in self.m.server_capabilities] |
| 72 | + result['client_capabilities'] = [c for c in self.m.client_capabilities] |
| 73 | + result['session_id'] = self.m.session_id |
| 74 | + result['device_operations'] = self.get_device_operations(result['server_capabilities']) |
| 75 | + return json.dumps(result) |
| 76 | + |
| 77 | + @staticmethod |
| 78 | + def guess_network_os(obj): |
| 79 | + try: |
| 80 | + m = manager.connect( |
| 81 | + host=obj._play_context.remote_addr, |
| 82 | + port=obj._play_context.port or 830, |
| 83 | + username=obj._play_context.remote_user, |
| 84 | + password=obj._play_context.password, |
| 85 | + key_filename=obj._play_context.private_key_file, |
| 86 | + hostkey_verify=C.HOST_KEY_CHECKING, |
| 87 | + look_for_keys=C.PARAMIKO_LOOK_FOR_KEYS, |
| 88 | + allow_agent=obj._play_context.allow_agent, |
| 89 | + timeout=obj._play_context.timeout |
| 90 | + ) |
| 91 | + except SSHUnknownHostError as exc: |
| 92 | + raise AnsibleConnectionFailure(str(exc)) |
| 93 | + |
| 94 | + guessed_os = None |
| 95 | + for c in m.server_capabilities: |
| 96 | + if re.search('urn:nokia.com:sros:ns:yang:sr', c): |
| 97 | + guessed_os = 'sros' |
| 98 | + |
| 99 | + m.close_session() |
| 100 | + return guessed_os |
0 commit comments