From 58d446e61afe3e923d60fc7a8734d47860f3d86f Mon Sep 17 00:00:00 2001 From: Sumit Jaiswal Date: Fri, 21 Jun 2019 16:18:59 +0530 Subject: [PATCH] PR to fix where ansible_net_model was not being populated (#58159) * fix bug 57285 Signed-off-by: Sumit Jaiswal * minor fix Signed-off-by: Sumit Jaiswal * adding TC fix related Signed-off-by: Sumit Jaiswal * fix shippable error Signed-off-by: Sumit Jaiswal --- lib/ansible/plugins/cliconf/ios.py | 9 +- .../plugins/cliconf/fixtures/ios/show_version | 54 ++++++++ test/units/plugins/cliconf/test_ios.py | 131 ++++++++++++++++++ 3 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 test/units/plugins/cliconf/fixtures/ios/show_version create mode 100644 test/units/plugins/cliconf/test_ios.py diff --git a/lib/ansible/plugins/cliconf/ios.py b/lib/ansible/plugins/cliconf/ios.py index 94485bc4837..a3fe570c7c7 100644 --- a/lib/ansible/plugins/cliconf/ios.py +++ b/lib/ansible/plugins/cliconf/ios.py @@ -207,9 +207,12 @@ class Cliconf(CliconfBase): if match: device_info['network_os_version'] = match.group(1).strip(',') - match = re.search(r'^Cisco (.+) \(revision', data, re.M) - if match: - device_info['network_os_model'] = match.group(1) + model_search_strs = [r'^Cisco (.+) \(revision', r'^[Cc]isco (\S+).+bytes of .*memory'] + for item in model_search_strs: + match = re.search(item, data, re.M) + if match: + device_info['network_os_model'] = match.group(1) + break match = re.search(r'^(.+) uptime', data, re.M) if match: diff --git a/test/units/plugins/cliconf/fixtures/ios/show_version b/test/units/plugins/cliconf/fixtures/ios/show_version new file mode 100644 index 00000000000..eadd3d3ad1f --- /dev/null +++ b/test/units/plugins/cliconf/fixtures/ios/show_version @@ -0,0 +1,54 @@ +Cisco IOS XE Software, Version 16.06.01 +Cisco IOS Software [Everest], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.6.1, RELEASE SOFTWARE (fc2) +Technical Support: http://www.cisco.com/techsupport +Copyright (c) 1986-2017 by Cisco Systems, Inc. +Compiled Sat 22-Jul-17 05:51 by mcpre + + +Cisco IOS-XE software, Copyright (c) 2005-2017 by cisco Systems, Inc. +All rights reserved. Certain components of Cisco IOS-XE software are +licensed under the GNU General Public License ("GPL") Version 2.0. The +software code licensed under GPL Version 2.0 is free software that comes +with ABSOLUTELY NO WARRANTY. You can redistribute and/or modify such +GPL code under the terms of GPL Version 2.0. For more details, see the +documentation or "License Notice" file accompanying the IOS-XE software, +or the applicable URL provided on the flyer accompanying the IOS-XE +software. + + +ROM: IOS-XE ROMMON + +an-csr-01 uptime is 1 day, 16 hours, 15 minutes +Uptime for this control processor is 1 day, 16 hours, 16 minutes +System returned to ROM by reload +System image file is "bootflash:packages.conf" +Last reload reason: Reload Command + + + +This product contains cryptographic features and is subject to United +States and local country laws governing import, export, transfer and +use. Delivery of Cisco cryptographic products does not imply +third-party authority to import, export, distribute or use encryption. +Importers, exporters, distributors and users are responsible for +compliance with U.S. and local country laws. By using this product you +agree to comply with applicable laws and regulations. If you are unable +to comply with U.S. and local laws, return this product immediately. + +A summary of U.S. laws governing Cisco cryptographic products may be found at: +http://www.cisco.com/wwl/export/crypto/tool/stqrg.html + +If you require further assistance please contact us by sending email to +export@cisco.com. + +License Level: ax +License Type: Default. No valid license found. +Next reload license Level: ax + +cisco CSR1000V (VXE) processor (revision VXE) with 1225511K/3075K bytes of memory. +Processor board ID 9I5BX4UHSO4 +3 Gigabit Ethernet interfaces +32768K bytes of non-volatile configuration memory. +3018776K bytes of physical memory. +16162815K bytes of virtual hard disk at bootflash:. +0K bytes of WebUI ODM Files at webui:. diff --git a/test/units/plugins/cliconf/test_ios.py b/test/units/plugins/cliconf/test_ios.py new file mode 100644 index 00000000000..c60b69ec67c --- /dev/null +++ b/test/units/plugins/cliconf/test_ios.py @@ -0,0 +1,131 @@ +# +# (c) 2019 Red Hat Inc. +# +# 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 os import path +import json + +from mock import MagicMock, call + +from units.compat import unittest +from ansible.plugins.cliconf import ios + +FIXTURE_DIR = b'%s/fixtures/ios' % ( + path.dirname(path.abspath(__file__)).encode('utf-8') +) + + +def _connection_side_effect(*args, **kwargs): + try: + if args: + value = args[0] + else: + value = kwargs.get('command') + + fixture_path = path.abspath( + b'%s/%s' % (FIXTURE_DIR, b'_'.join(value.split(b' '))) + ) + with open(fixture_path, 'rb') as file_desc: + return file_desc.read() + except (OSError, IOError): + if args: + value = args[0] + return value + elif kwargs.get('command'): + value = kwargs.get('command') + return value + + return 'Nope' + + +class TestPluginCLIConfIOS(unittest.TestCase): + """ Test class for IOS CLI Conf Methods + """ + def setUp(self): + self._mock_connection = MagicMock() + self._mock_connection.send.side_effect = _connection_side_effect + self._cliconf = ios.Cliconf(self._mock_connection) + self.maxDiff = None + + def tearDown(self): + pass + + def test_get_device_info(self): + """ Test get_device_info + """ + device_info = self._cliconf.get_device_info() + + mock_device_info = {'network_os': 'ios', + 'network_os_model': 'CSR1000V', + 'network_os_version': '16.06.01', + 'network_os_hostname': 'an-csr-01', + 'network_os_image': 'bootflash:packages.conf' + } + + self.assertEqual(device_info, mock_device_info) + + def test_get_capabilities(self): + """ Test get_capabilities + """ + capabilities = json.loads(self._cliconf.get_capabilities()) + mock_capabilities = { + 'network_api': 'cliconf', + 'rpc': [ + 'get_config', + 'edit_config', + 'get_capabilities', + 'get', + 'enable_response_logging', + 'disable_response_logging', + 'edit_banner', + 'get_diff', + 'run_commands', + 'get_defaults_flag' + ], + 'device_operations': { + 'supports_diff_replace': True, + 'supports_commit': False, + 'supports_rollback': False, + 'supports_defaults': True, + 'supports_onbox_diff': False, + 'supports_commit_comment': False, + 'supports_multiline_delimiter': True, + 'supports_diff_match': True, + 'supports_diff_ignore_lines': True, + 'supports_generate_diff': True, + 'supports_replace': False + }, + 'device_info': { + 'network_os_hostname': 'an-csr-01', + 'network_os_image': 'bootflash:packages.conf', + 'network_os_model': 'CSR1000V', + 'network_os_version': '16.06.01', + 'network_os': 'ios' + }, + 'format': ['text'], + 'diff_match': ['line', 'strict', 'exact', 'none'], + 'diff_replace': ['line', 'block'], + 'output': [] + } + + self.assertEqual( + mock_capabilities, + capabilities + )