Skip to content

Commit 12f29ea

Browse files
authored
Merge pull request #16 from QualiSystems/development
Development
2 parents a7f7ae1 + eeba58c commit 12f29ea

33 files changed

+3475
-0
lines changed

.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
language: python
2+
python:
3+
- "2.7"
4+
5+
install:
6+
- pip install -r requirements.txt
7+
- pip install -r test_requirements.txt
8+
- pip install coveralls
9+
10+
script:
11+
- python runtests.py --with-coverage --cover-package=package
12+
- python setup.py test
13+
- python setup.py sdist --format zip
14+
15+
after_success:
16+
coveralls

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include *.txt
2+
global-include *.ini

cloudshell/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from pkgutil import extend_path
2+
__path__ = extend_path(__path__, __name__)

cloudshell/networking/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from pkgutil import extend_path
2+
__path__ = extend_path(__path__, __name__)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from pkgutil import extend_path
2+
__path__ = extend_path(__path__, __name__)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from pkgutil import extend_path
2+
__path__ = extend_path(__path__, __name__)
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import re
2+
import inject
3+
from cloudshell.shell.core.driver_context import AutoLoadDetails
4+
from cloudshell.networking.autoload.networking_autoload_resource_attributes import NetworkingStandardRootAttributes
5+
from cloudshell.networking.huawei.autoload.mib_attributes import MibAttributes
6+
7+
8+
class HuaweiGenericSNMPAutoload(MibAttributes):
9+
10+
def __init__(self, snmp_handler=None, logger=None, supported_os=None):
11+
"""Basic init with huawei router mib attribuites handler and logger
12+
13+
:param snmp_handler:
14+
:param logger:
15+
:return:
16+
"""
17+
18+
MibAttributes.__init__(self, snmp_handler, logger, supported_os)
19+
self._logger = logger
20+
self._excluded_models = []
21+
self.supported_os = supported_os
22+
23+
@property
24+
def logger(self):
25+
if self._logger is None:
26+
try:
27+
self._logger = inject.instance('logger')
28+
except:
29+
raise Exception('HuaweiAutoload', 'Logger is none or empty')
30+
return self._logger
31+
32+
def discover(self):
33+
"""Load device structure and attributes: chassis, modules, submodules, ports, port-channels and power supplies
34+
35+
:return: AutoLoadDetails object
36+
"""
37+
#
38+
self._is_valid_device_os()
39+
40+
self.logger.info('*'*10)
41+
self.logger.info('Starting huawei SNMP discovery process')
42+
43+
self.load_huawei_mib()
44+
self._get_device_details()
45+
self.snmp.load_mib(['HUAWEI-PORT-MIB'])
46+
self._load_snmp_objects_and_tables()
47+
48+
49+
if len(self.chassis_list) < 1:
50+
self.logger.error('Entity table error, no chassis found')
51+
return AutoLoadDetails(list(), list())
52+
53+
for chassis in self.chassis_list:
54+
if chassis not in self.exclusion_list:
55+
chassis_id = self._get_resource_id(chassis)
56+
if chassis_id == '-1':
57+
chassis_id = '0'
58+
self.relative_path[chassis] = chassis_id
59+
60+
self._filter_lower_bay_containers()
61+
self.get_module_list()
62+
self.add_relative_paths()
63+
self._get_chassis_attributes(self.chassis_list)
64+
self._get_ports_attributes()
65+
self._get_module_attributes()
66+
self._get_power_ports()
67+
self._get_port_channels()
68+
69+
result = AutoLoadDetails(resources=self.resources, attributes=self.attributes)
70+
71+
self.logger.info('*'*10)
72+
self.logger.info('Discover completed. The following Structure have been loaded:' +
73+
'\nModel, Name, Relative Path, Uniqe Id')
74+
75+
for resource in self.resources:
76+
self.logger.info('{0},\t\t{1},\t\t{2},\t\t{3}'.format(resource.model, resource.name,
77+
resource.relative_address, resource.unique_identifier))
78+
self.logger.info('------------------------------')
79+
for attribute in self.attributes:
80+
self.logger.info('{0},\t\t{1},\t\t{2}'.format(attribute.relative_address, attribute.attribute_name,
81+
attribute.attribute_value))
82+
83+
self.logger.info('*'*10)
84+
self.logger.info('SNMP discovery Completed')
85+
return result
86+
87+
def _is_valid_device_os(self):
88+
"""Validate device OS using snmp
89+
:return: True or False
90+
"""
91+
92+
version = None
93+
if not self.supported_os:
94+
config = inject.instance('config')
95+
self.supported_os = config.SUPPORTED_OS
96+
system_description = self.sys_descr
97+
print system_description
98+
match_str = re.sub('[\n\r]+', ' ', system_description.upper())
99+
res = re.search('\s+(VRP)\s*', match_str)
100+
if res:
101+
version = res.group(0).strip(' \s\r\n')
102+
if version and version in self.supported_os:
103+
return
104+
105+
self.logger.info('System description from device: \'{0}\''.format(system_description))
106+
107+
error_message = 'Incompatible driver! Please use correct resource driver for {0} operation system(s)'. \
108+
format(str(tuple(self.supported_os)))
109+
self.logger.error(error_message)
110+
raise Exception(error_message)
111+
112+
113+
114+
115+
116+
def _filter_lower_bay_containers(self):
117+
118+
upper_container = None
119+
lower_container = None
120+
containers = self.entity_mib_table.filter_by_column('Class', "container").sort_by_column('ParentRelPos').keys()
121+
for container in containers:
122+
vendor_type = self.snmp.get_property('ENTITY-MIB', 'entPhysicalVendorType', container)
123+
if 'uppermodulebay' in vendor_type.lower():
124+
upper_container = container
125+
if 'lowermodulebay' in vendor_type.lower():
126+
lower_container = container
127+
if lower_container and upper_container:
128+
child_upper_items_len = len(self.entity_mib_table.filter_by_column('ContainedIn', str(upper_container)
129+
).sort_by_column('ParentRelPos').keys())
130+
child_lower_items = self.entity_mib_table.filter_by_column('ContainedIn', str(lower_container)
131+
).sort_by_column('ParentRelPos').keys()
132+
for child in child_lower_items:
133+
self.entity_mib_table[child]['entPhysicalContainedIn'] = upper_container
134+
self.entity_mib_table[child]['entPhysicalParentRelPos'] = str(child_upper_items_len + int(
135+
self.entity_mib_table[child]['entPhysicalParentRelPos']))
136+
137+
138+
139+
def _add_resource(self, resource):
140+
"""Add object data to resources and attributes lists
141+
142+
:param resource: object which contains all required data for certain resource
143+
"""
144+
145+
self.resources.append(resource.get_autoload_resource_details())
146+
self.attributes.extend(resource.get_autoload_resource_attributes())
147+
148+
149+
150+
151+
152+
def _filter_entity_table(self, raw_entity_table):
153+
"""Filters out all elements if their parents, doesn't exist, or listed in self.exclusion_list
154+
155+
:param raw_entity_table: entity table with unfiltered elements
156+
"""
157+
158+
elements = raw_entity_table.filter_by_column('ContainedIn').sort_by_column('ParentRelPos').keys()
159+
for element in reversed(elements):
160+
parent_id = int(self.entity_mib_table[element]['entPhysicalContainedIn'])
161+
162+
if parent_id not in raw_entity_table or parent_id in self.exclusion_list:
163+
self.exclusion_list.append(element)
164+
165+
166+
def _get_device_details(self):
167+
"""Get root element attributes
168+
169+
"""
170+
171+
self.logger.info('Start loading Switch Attributes')
172+
result = {'system_name': self.sys_name,
173+
'vendor': self.vendor,
174+
'model': self._get_device_model(),
175+
'location': self.sys_location,
176+
'contact': self.sys_contact,
177+
'version': ''}
178+
software_dscription = self.sys_descr
179+
print software_dscription
180+
match_version = re.search('Version\s+(?P<software_version>\S+)\S*\s+',
181+
software_dscription)
182+
if match_version:
183+
result['version'] = match_version.groupdict()['software_version'].replace(',', '')
184+
185+
root = NetworkingStandardRootAttributes(**result)
186+
self.attributes.extend(root.get_autoload_resource_attributes())
187+
self.logger.info('Finished Loading Switch Attributes')
188+
189+
190+
191+
def _get_device_model(self):
192+
"""Get device model form snmp SNMPv2 mib
193+
194+
:return: device model
195+
:rtype: str
196+
"""
197+
198+
result = ''
199+
match_name = re.search(r'::(?P<model>\S+$)', self.snmp_object_id)
200+
if match_name:
201+
result = match_name.groupdict()['model'].capitalize()
202+
return result
203+
204+

0 commit comments

Comments
 (0)